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 /**   Point-to-Point Protocol (PPP)                                       */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_PPP_SOURCE_CODE
23 
24 
25 /* Force error checking to be disabled in this module */
26 #include "tx_port.h"
27 
28 #ifndef NX_DISABLE_ERROR_CHECKING
29 #define NX_DISABLE_ERROR_CHECKING
30 #endif
31 
32 #ifndef TX_SAFETY_CRITICAL
33 #ifndef TX_DISABLE_ERROR_CHECKING
34 #define TX_DISABLE_ERROR_CHECKING
35 #endif
36 #endif
37 
38 
39 /* Include necessary system files.  */
40 
41 #include "nx_api.h"
42 #ifndef NX_DISABLE_IPV4
43 #include "nx_ppp.h"
44 #ifndef NX_PPP_DISABLE_CHAP
45 #include "nx_md5.h"
46 #endif
47 
48 /* Define global PPP variables and data structures.  */
49 
50 /* Define the PPP created list head pointer and count.  */
51 
52 NX_PPP  *_nx_ppp_created_ptr =       NX_NULL;
53 ULONG    _nx_ppp_created_count =     0;
54 
55 
56 /* Define the CRC lookup table.  This is used to improve the
57    CRC calculation performance.  */
58 
59 const USHORT _nx_ppp_crc_table[256] =
60 {
61     0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
62     0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
63     0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
64     0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
65     0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
66     0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
67     0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
68     0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
69     0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
70     0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
71     0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
72     0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
73     0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
74     0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
75     0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
76     0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
77     0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
78     0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
79     0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
80     0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
81     0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
82     0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
83     0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
84     0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
85     0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
86     0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
87     0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
88     0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
89     0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
90     0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
91     0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
92     0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
93 };
94 
95 
96 /* Bring in externs for caller checking code.  */
97 
98 NX_CALLER_CHECKING_EXTERNS
99 
100 
101 /**************************************************************************/
102 /*                                                                        */
103 /*  FUNCTION                                               RELEASE        */
104 /*                                                                        */
105 /*    _nx_ppp_thread_entry                                PORTABLE C      */
106 /*                                                           6.1          */
107 /*  AUTHOR                                                                */
108 /*                                                                        */
109 /*    Yuxin Zhou, Microsoft Corporation                                   */
110 /*                                                                        */
111 /*  DESCRIPTION                                                           */
112 /*                                                                        */
113 /*    This function handles all PPP processing, including assembly of     */
114 /*    PPP requests and dispatching them.                                  */
115 /*                                                                        */
116 /*  INPUT                                                                 */
117 /*                                                                        */
118 /*    ppp_addr                              Address of PPP instance       */
119 /*                                                                        */
120 /*  OUTPUT                                                                */
121 /*                                                                        */
122 /*    None                                                                */
123 /*                                                                        */
124 /*  CALLS                                                                 */
125 /*                                                                        */
126 /*    tx_event_flags_get                    Get PPP event flags           */
127 /*    nx_packet_release                     Release packet                */
128 /*    _nx_ppp_chap_state_machine_update     Update CHAP state machine     */
129 /*    _nx_ppp_lcp_state_machine_update      Update LCP state machine      */
130 /*    _nx_ppp_process_deferred_ip_packet_send                             */
131 /*                                          Process deferred IP packet    */
132 /*                                            send                        */
133 /*    _nx_ppp_process_deferred_raw_string_send                            */
134 /*                                          Process deferred raw string   */
135 /*                                            send                        */
136 /*    _nx_ppp_receive_packet_get            Get PPP receive packet        */
137 /*    _nx_ppp_receive_packet_process        Process received PPP packet   */
138 /*    _nx_ppp_timeout                       Process PPP timeout           */
139 /*    [_nx_ppp_debug_log_capture]           Optional PPP debug log        */
140 /*                                                                        */
141 /*  CALLED BY                                                             */
142 /*                                                                        */
143 /*    ThreadX                                                             */
144 /*                                                                        */
145 /*  RELEASE HISTORY                                                       */
146 /*                                                                        */
147 /*    DATE              NAME                      DESCRIPTION             */
148 /*                                                                        */
149 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
150 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
151 /*                                            resulting in version 6.1    */
152 /*                                                                        */
153 /**************************************************************************/
_nx_ppp_thread_entry(ULONG ppp_addr)154 void _nx_ppp_thread_entry(ULONG ppp_addr)
155 {
156 
157 TX_INTERRUPT_SAVE_AREA
158 
159 NX_PPP      *ppp_ptr;
160 ULONG       ppp_events;
161 NX_PACKET   *packet_ptr;
162 NX_PACKET   *next_packet_ptr;
163 ULONG       count;
164 
165 
166     /* Setup the PPP pointer.  */
167     ppp_ptr =  (NX_PPP *) ppp_addr;
168 
169     /* Loop to continue processing incoming bytes.  */
170     while(NX_FOREVER)
171     {
172 
173 
174 #ifdef NX_PPP_DEBUG_LOG_PRINT_PROTOCOL
175         /* Display debug output of PPP protocol status.   */
176         _nx_ppp_debug_log_capture_protocol(ppp_ptr);
177 #endif
178 
179         /* Wait for PPP event(s). The timeout on the wait will drive PPP timeout processing
180            as well.  */
181         tx_event_flags_get(&(ppp_ptr -> nx_ppp_event), (ULONG) 0xFFFFFFFF, TX_OR_CLEAR, &ppp_events, NX_WAIT_FOREVER);
182 
183         /* Check for PPP stop event.  */
184         if (ppp_events & NX_PPP_EVENT_STOP)
185         {
186 
187             /* Is PPP already stopped?  */
188             if (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED)
189             {
190 
191                 /* No, stop this PPP instance an prepare for the next start operation.  */
192 
193                 /* Set state to stopped.  */
194                 ppp_ptr -> nx_ppp_state =  NX_PPP_STOPPED;
195 
196                 /* Clean up resources and prepare for next PPP start.  */
197 
198                 /* Release any packets queued up for the PPP instance.  */
199 
200                 /* Release any partial receive packets.  */
201                 if (ppp_ptr -> nx_ppp_receive_partial_packet)
202                     nx_packet_release(ppp_ptr -> nx_ppp_receive_partial_packet);
203 
204                 /* Clear the saved receive packet.  */
205                 ppp_ptr -> nx_ppp_receive_partial_packet =  NX_NULL;
206 
207                 /* Setup the receive buffer processing.  */
208                 ppp_ptr -> nx_ppp_serial_buffer_write_index =  0;
209                 ppp_ptr -> nx_ppp_serial_buffer_read_index =   0;
210                 ppp_ptr -> nx_ppp_serial_buffer_byte_count =   0;
211 
212 #ifdef NX_PPP_PPPOE_ENABLE
213 
214                 /* Loop to release all packets in the deferred processing queue..  */
215                 while (ppp_ptr -> nx_ppp_deferred_received_packet_head)
216                 {
217 
218                     /* Restore interrupts.  */
219                     TX_RESTORE
220 
221                     /* Pickup the packet.  */
222                     packet_ptr =  ppp_ptr -> nx_ppp_deferred_received_packet_head;
223 
224                     /* Move the head pointer to the next packet.  */
225                     ppp_ptr -> nx_ppp_deferred_received_packet_head =  packet_ptr -> nx_packet_queue_next;
226 
227                     /* Check for end of deferred processing queue.  */
228                     if (ppp_ptr -> nx_ppp_deferred_received_packet_head == NX_NULL)
229                     {
230 
231                         /* Yes, the queue is empty.  Set the tail pointer to NULL.  */
232                         ppp_ptr -> nx_ppp_deferred_received_packet_tail =  NX_NULL;
233                     }
234 
235                     /* Release all packets in the raw packet queue.  */
236                     TX_DISABLE
237 
238                     /* Release packet.  */
239                     nx_packet_release(packet_ptr);
240                 }
241 #endif /* NX_PPP_PPPOE_ENABLE  */
242 
243                 /* Release all packets in the IP packet queue.  */
244                 TX_DISABLE
245 
246                 /* Pickup the head pointer and count.  */
247                 packet_ptr =  ppp_ptr -> nx_ppp_ip_packet_queue_head;
248 
249                 /* Set the list head and tail pointers to NULL.  */
250                 ppp_ptr -> nx_ppp_ip_packet_queue_head =  NX_NULL;
251                 ppp_ptr -> nx_ppp_ip_packet_queue_tail =  NX_NULL;
252 
253                 /* Pickup the count.  */
254                 count =  ppp_ptr -> nx_ppp_ip_packet_queue_count;
255 
256                 /* Clear the count.  */
257                 ppp_ptr -> nx_ppp_ip_packet_queue_count =  0;
258 
259                 /* Restore interrupts.  */
260                 TX_RESTORE
261 
262                 /* Loop to release all packets.  */
263                 while (count)
264                 {
265                     /* Pickup next packet.  */
266                     next_packet_ptr =  packet_ptr -> nx_packet_queue_next;
267 
268                     /* Release packet.  */
269                     nx_packet_release(packet_ptr);
270 
271                     /* Move to next packet.  */
272                     packet_ptr =  next_packet_ptr;
273 
274                     /* Decrement the count.  */
275                     count--;
276                 }
277 
278                 /* Release all packets in the raw packet queue.  */
279                 TX_DISABLE
280 
281                 /* Pickup the head pointer and count.  */
282                 packet_ptr =  ppp_ptr -> nx_ppp_raw_packet_queue_head;
283 
284                 /* Set the list head and tail pointers to NULL.  */
285                 ppp_ptr -> nx_ppp_raw_packet_queue_head =  NX_NULL;
286                 ppp_ptr -> nx_ppp_raw_packet_queue_tail =  NX_NULL;
287 
288                 /* Pickup the count.  */
289                 count =  ppp_ptr -> nx_ppp_raw_packet_queue_count;
290 
291                 /* Clear the count.  */
292                 ppp_ptr -> nx_ppp_raw_packet_queue_count =  0;
293 
294                 /* Restore interrupts.  */
295                 TX_RESTORE
296 
297                 /* Loop to release all packets.  */
298                 while (count)
299                 {
300                     /* Pickup next packet.  */
301                     next_packet_ptr =  packet_ptr -> nx_packet_queue_next;
302 
303                     /* Release packet.  */
304                     nx_packet_release(packet_ptr);
305 
306                     /* Move to next packet.  */
307                     packet_ptr =  next_packet_ptr;
308 
309                     /* Decrement the count.  */
310                     count--;
311                 }
312 
313                 /* Reset all state machines.  */
314                 ppp_ptr -> nx_ppp_lcp_state =   NX_PPP_LCP_INITIAL_STATE;
315                 ppp_ptr -> nx_ppp_pap_state =   NX_PPP_PAP_INITIAL_STATE;
316                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_INITIAL_STATE;
317                 ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_INITIAL_STATE;
318 
319                 /* Determine how to setup the initial authenticated field.  */
320                 if ((ppp_ptr -> nx_ppp_pap_verify_login) ||
321                     (ppp_ptr -> nx_ppp_pap_generate_login) ||
322                     (ppp_ptr -> nx_ppp_chap_get_verification_values))
323                 {
324                     ppp_ptr -> nx_ppp_authenticated =  NX_FALSE;
325                 }
326                 else
327                     ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
328 
329                 /* Clear the IP address.  */
330                 nx_ip_interface_address_set(ppp_ptr -> nx_ppp_ip_ptr, ppp_ptr -> nx_ppp_interface_index, 0, 0);
331 
332                 /* Clear the local information for PPP client.  */
333                 if (ppp_ptr -> nx_ppp_server == NX_FALSE)
334                 {
335 
336                     /* Clear the IP addresses.  */
337                     ppp_ptr -> nx_ppp_ipcp_local_ip[0] = 0;
338                     ppp_ptr -> nx_ppp_ipcp_local_ip[1] = 0;
339                     ppp_ptr -> nx_ppp_ipcp_local_ip[2] = 0;
340                     ppp_ptr -> nx_ppp_ipcp_local_ip[3] = 0;
341                     ppp_ptr -> nx_ppp_ipcp_peer_ip[0] = 0;
342                     ppp_ptr -> nx_ppp_ipcp_peer_ip[1] = 0;
343                     ppp_ptr -> nx_ppp_ipcp_peer_ip[2] = 0;
344                     ppp_ptr -> nx_ppp_ipcp_peer_ip[3] = 0;
345 
346                     /* Clear the DNS addresses.  */
347                     ppp_ptr -> nx_ppp_primary_dns_address =  0;
348                     ppp_ptr -> nx_ppp_secondary_dns_address =  0;
349                 }
350             }
351         }
352 
353         /* Check for PPP start event.  */
354         if (ppp_events & NX_PPP_EVENT_START)
355         {
356 
357             /* Is PPP in a stopped state?  */
358             if (ppp_ptr -> nx_ppp_state == NX_PPP_STOPPED)
359             {
360 
361                 /* Update the PPP state.  */
362                 ppp_ptr -> nx_ppp_state =  NX_PPP_STARTED;
363 
364                 /* Yes, move to the initial LCP state.  */
365                 ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_START_STATE;
366 
367                 /* Initiate the PPP protocol.  */
368                 _nx_ppp_lcp_state_machine_update(ppp_ptr, NX_NULL);
369             }
370         }
371 
372         /* Check for PPP raw packet send request.  */
373         if (ppp_events & NX_PPP_EVENT_RAW_STRING_SEND)
374         {
375 
376             /* Process deferred raw string send requests.  */
377             _nx_ppp_process_deferred_raw_string_send(ppp_ptr);
378         }
379 
380         /* Check for deferred IP transmit requests.  */
381         if (ppp_events & NX_PPP_EVENT_IP_PACKET_SEND)
382         {
383 
384             /* Process deferred IP transmit packets.  */
385             _nx_ppp_process_deferred_ip_packet_send(ppp_ptr);
386         }
387 
388 #ifndef NX_PPP_DISABLE_CHAP
389 
390         /* Check for CHAP challenge event.  */
391         if (ppp_events & NX_PPP_EVENT_CHAP_CHALLENGE)
392         {
393 
394             /* Determine if CHAP is in a completed state.  */
395             if (ppp_ptr -> nx_ppp_chap_state == NX_PPP_CHAP_COMPLETED_STATE)
396             {
397 
398                 /* Move the state to the new challenge state.  */
399                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_COMPLETED_NEW_STATE;
400 
401                 /* Now update the CHAP state machine in order to force the
402                    new CHAP challenge out.  */
403                 _nx_ppp_chap_state_machine_update(ppp_ptr, NX_NULL);
404             }
405         }
406 #endif
407 
408         /* Now check for timeout processing.  */
409         if (ppp_events & NX_PPP_EVENT_TIMEOUT)
410         {
411 
412             /* Timeout occurred. Is there are PPP timeout active?   */
413             if (ppp_ptr -> nx_ppp_timeout)
414             {
415 
416                 /* Decrement the timeout count.  */
417                 ppp_ptr -> nx_ppp_timeout--;
418 
419                 /* Has the timeout expired?  */
420                 if (ppp_ptr -> nx_ppp_timeout == 0)
421                 {
422 
423                     /* Process timeout request.  */
424                     _nx_ppp_timeout(ppp_ptr);
425                 }
426             }
427 
428             /* Increment the receive timeout processing.   */
429             ppp_ptr -> nx_ppp_receive_timeouts++;
430         }
431 
432         /* Check for PPP Packet receive event.  */
433         if (ppp_events & NX_PPP_EVENT_PACKET_RECEIVE)
434         {
435 
436             /* Pickup the next PPP packet from serial port to process. This is called whether an event was set or not
437                simply to handle the case when a non-PPP frame is received.  */
438             _nx_ppp_receive_packet_get(ppp_ptr, &packet_ptr);
439 
440             /* Now determine if there is a packet to process.  */
441             if (packet_ptr)
442             {
443 
444 #ifdef NX_PPP_DEBUG_LOG_ENABLE
445 
446                 /* Insert an entry into the PPP frame debug log.  */
447                 _nx_ppp_debug_log_capture(ppp_ptr, 'R', packet_ptr);
448 #endif
449 
450                 /* Yes, call the PPP packet processing routine.  */
451                 _nx_ppp_receive_packet_process(ppp_ptr, packet_ptr);
452             }
453         }
454 
455 #ifdef NX_PPP_PPPOE_ENABLE
456 
457         /* Check for PPP Packet receive event.  */
458         if (ppp_events & NX_PPP_EVENT_PPPOE_PACKET_RECEIVE)
459         {
460 
461             /* Loop to process all deferred packet requests.  */
462             while (ppp_ptr -> nx_ppp_deferred_received_packet_head)
463             {
464 
465                 /* Remove the first packet and process it!  */
466 
467                 /* Disable interrupts.  */
468                 TX_DISABLE
469 
470                 /* Pickup the first packet.  */
471                 packet_ptr =  ppp_ptr -> nx_ppp_deferred_received_packet_head;
472 
473                 /* Move the head pointer to the next packet.  */
474                 ppp_ptr -> nx_ppp_deferred_received_packet_head =  packet_ptr -> nx_packet_queue_next;
475 
476                 /* Check for end of deferred processing queue.  */
477                 if (ppp_ptr -> nx_ppp_deferred_received_packet_head == NX_NULL)
478                 {
479 
480                     /* Yes, the queue is empty.  Set the tail pointer to NULL.  */
481                     ppp_ptr -> nx_ppp_deferred_received_packet_tail =  NX_NULL;
482                 }
483 
484                 /* Restore interrupts.  */
485                 TX_RESTORE
486 
487 #ifdef NX_PPP_DEBUG_LOG_ENABLE
488 
489                 /* Insert an entry into the PPP frame debug log.  */
490                 _nx_ppp_debug_log_capture(ppp_ptr, 'R', packet_ptr);
491 #endif
492 
493                 /* Yes, call the PPP packet processing routine.  */
494                 _nx_ppp_receive_packet_process(ppp_ptr, packet_ptr);
495             }
496         }
497 #endif /* NX_PPP_PPPOE_ENABLE  */
498     }
499 }
500 
501 
502 /**************************************************************************/
503 /*                                                                        */
504 /*  FUNCTION                                               RELEASE        */
505 /*                                                                        */
506 /*    _nx_ppp_driver                                      PORTABLE C      */
507 /*                                                           6.1          */
508 /*  AUTHOR                                                                */
509 /*                                                                        */
510 /*    Yuxin Zhou, Microsoft Corporation                                   */
511 /*                                                                        */
512 /*  DESCRIPTION                                                           */
513 /*                                                                        */
514 /*    This function provides the basic interface to the NetX TCP/IP       */
515 /*    network stack.                                                      */
516 /*                                                                        */
517 /*  INPUT                                                                 */
518 /*                                                                        */
519 /*    driver_req_ptr                        NetX driver request structure */
520 /*                                                                        */
521 /*  OUTPUT                                                                */
522 /*                                                                        */
523 /*    None                                                                */
524 /*                                                                        */
525 /*  CALLS                                                                 */
526 /*                                                                        */
527 /*    nx_packet_transmit_release            Release transmit packet       */
528 /*    tx_event_flags_set                    Set PPP events                */
529 /*    tx_thread_resume                      Resume PPP thread             */
530 /*    tx_timer_activate                     Activate PPP timer            */
531 /*                                                                        */
532 /*  CALLED BY                                                             */
533 /*                                                                        */
534 /*    NetX                                                                */
535 /*                                                                        */
536 /*  RELEASE HISTORY                                                       */
537 /*                                                                        */
538 /*    DATE              NAME                      DESCRIPTION             */
539 /*                                                                        */
540 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
541 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
542 /*                                            resulting in version 6.1    */
543 /*                                                                        */
544 /**************************************************************************/
_nx_ppp_driver(NX_IP_DRIVER * driver_req_ptr)545 void  _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr)
546 {
547 
548 TX_INTERRUPT_SAVE_AREA
549 
550 NX_IP           *ip_ptr;
551 NX_INTERFACE    *interface_ptr;
552 NX_PPP          *ppp_ptr;
553 NX_PACKET       *packet_ptr;
554 UINT            i;
555 
556 
557     /* Setup the IP pointer from the driver request.  */
558     ip_ptr =  driver_req_ptr -> nx_ip_driver_ptr;
559 
560     /* Pickup the interface pointer.  */
561     interface_ptr =  driver_req_ptr -> nx_ip_driver_interface;
562 
563     /* Default to successful return.  */
564     driver_req_ptr -> nx_ip_driver_status =  NX_SUCCESS;
565 
566     /* Process according to the driver request type in the driver control
567        block.  */
568     switch (driver_req_ptr -> nx_ip_driver_command)
569     {
570 
571         case NX_LINK_INTERFACE_ATTACH:
572         {
573 
574             /* First, we need to find the PPP instance that is mapped to
575                this IP instance and that doesn't have its interface attach
576                complete yet. This requires that PPP is created prior to
577                IP creation.  */
578             ppp_ptr =  _nx_ppp_created_ptr;
579             i =  0;
580             while (i < _nx_ppp_created_count)
581             {
582 
583                 /* Does this PPP instance point to the current IP instance?  */
584                 if ((ppp_ptr -> nx_ppp_ip_ptr == ip_ptr) && (ppp_ptr -> nx_ppp_interface_ptr == NX_NULL))
585                 {
586 
587                     /* Yes, we found an un-attached PPP instance for this IP interface instance. Get out of
588                        the search loop.  */
589                     break;
590                 }
591 
592                 /* Move the next PPP instance.  */
593                 ppp_ptr =  ppp_ptr -> nx_ppp_created_next;
594 
595                 /* Increment counter. */
596                 i++;
597             }
598 
599             /* Determine if a PPP instance was found.  */
600             if (i >= _nx_ppp_created_count)
601             {
602 
603                 /* Return an error to NetX.  */
604                 driver_req_ptr -> nx_ip_driver_status =  NX_IP_INTERNAL_ERROR;
605                 return;
606             }
607 
608             /* Now find interface index.  */
609             i =  0;
610             while (i < NX_MAX_PHYSICAL_INTERFACES)
611             {
612 
613                 /* Is this the interface index?  */
614                 if (&(ip_ptr -> nx_ip_interface[i]) == interface_ptr)
615                 {
616 
617                     /* Found the index, get out of the loop.  */
618                     break;
619                 }
620 
621                 /* Move to next interface.  */
622                 i++;
623             }
624 
625             /* Determine if the interface index was found.  */
626             if (i >= NX_MAX_PHYSICAL_INTERFACES)
627             {
628 
629                 /* Return an error to NetX.  */
630                 driver_req_ptr -> nx_ip_driver_status =  NX_IP_INTERNAL_ERROR;
631                 return;
632             }
633 
634             /* Otherwise, we have everything we need to perform the attachment.  */
635 
636             /* Remember the PPP instance pointer in the IP interface pointer.  */
637             interface_ptr -> nx_interface_additional_link_info = (void *) ppp_ptr;
638 
639             /* Remember the interface pointer and index in the PPP structure.  */
640             ppp_ptr -> nx_ppp_interface_ptr =    interface_ptr;
641             ppp_ptr -> nx_ppp_interface_index =  i;
642             break;
643         }
644 
645         case NX_LINK_INITIALIZE:
646         {
647 
648             /* Process driver initialization.  */
649 
650 
651             /* Otherwise, we have found the PPP instance, continue initialization.  */
652 
653             /* Pickup the associated PPP instance address.  */
654             ppp_ptr =  (NX_PPP *)  interface_ptr-> nx_interface_additional_link_info;
655 
656             /* Setup the link maximum transfer unit.  */
657             interface_ptr -> nx_interface_ip_mtu_size =  NX_PPP_MRU;
658 
659             /* Clear the hardware physical address, since there is no
660                such thing in PPP.  */
661             interface_ptr -> nx_interface_physical_address_msw =  0;
662             interface_ptr -> nx_interface_physical_address_lsw =  0;
663 
664             /* Indicate to the IP software that IP to physical mapping
665                is not required in PPP.  */
666             interface_ptr -> nx_interface_address_mapping_needed =  NX_FALSE;
667 
668             /* Set the link up to false. */
669             interface_ptr -> nx_interface_link_up =  NX_FALSE;
670 
671             /* Resume the PPP thread.  */
672             tx_thread_resume(&(ppp_ptr -> nx_ppp_thread));
673 
674             /* Activate the PPP timer.  */
675             tx_timer_activate(&(ppp_ptr -> nx_ppp_timer));
676             break;
677         }
678 
679 
680         case NX_LINK_ENABLE:
681         {
682 
683             /* Pickup the associated PPP instance address.  */
684             ppp_ptr =  (NX_PPP *)  interface_ptr-> nx_interface_additional_link_info;
685 
686             /* Now set event flag to start PPP.  */
687             tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_START, TX_OR);
688             break;
689         }
690 
691         case NX_LINK_DISABLE:
692         {
693 
694             /* Process driver link disable.  */
695 
696             /* Pickup the associated PPP instance address.  */
697             ppp_ptr =  (NX_PPP*)  interface_ptr-> nx_interface_additional_link_info;
698 
699             /* Now set event flag to start PPP.  */
700             tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
701             break;
702         }
703 
704         case NX_LINK_PACKET_SEND:
705         {
706 
707             /* Pickup the associated PPP instance address.  */
708             ppp_ptr =  (NX_PPP*)  interface_ptr -> nx_interface_additional_link_info;
709 
710             /* Pickup packet pointer.   */
711             packet_ptr =  driver_req_ptr -> nx_ip_driver_packet;
712 
713             /* Determine if the interface link is still up.  */
714             if (interface_ptr -> nx_interface_link_up == NX_FALSE)
715             {
716 
717 #ifndef NX_PPP_DISABLE_INFO
718 
719                 /* Increment the transmit frames dropped counter.  */
720                 ppp_ptr -> nx_ppp_transmit_frames_dropped++;
721 #endif
722                 /* No, release the packet.  */
723                 nx_packet_transmit_release(packet_ptr);
724                 break;
725             }
726 
727             /* Disable interrupts.   */
728             TX_DISABLE
729 
730             /* Determine if the transmit queue is empty.  */
731             if (ppp_ptr -> nx_ppp_ip_packet_queue_count++)
732             {
733 
734                 /* Not empty, simply link the new packet to the tail and update the tail.  */
735                 (ppp_ptr -> nx_ppp_ip_packet_queue_tail) -> nx_packet_queue_next =  packet_ptr;
736                 ppp_ptr -> nx_ppp_ip_packet_queue_tail =                            packet_ptr;
737             }
738             else
739             {
740 
741                 /* List is empty, set the head and tail to this packet.  */
742                 ppp_ptr -> nx_ppp_ip_packet_queue_head =  packet_ptr;
743                 ppp_ptr -> nx_ppp_ip_packet_queue_tail =  packet_ptr;
744             }
745 
746             /* Restore interrupts.  */
747             TX_RESTORE
748 
749             /* Set event flag to wake up PPP thread for processing.  */
750             tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_IP_PACKET_SEND, TX_OR);
751             break;
752         }
753 
754         case NX_LINK_GET_STATUS:
755         {
756 
757             /* Return the link status in the supplied return pointer.  */
758             *(driver_req_ptr -> nx_ip_driver_return_ptr) =  interface_ptr -> nx_interface_link_up;
759             break;
760         }
761 
762         case NX_LINK_UNINITIALIZE:
763         {
764 
765             break;
766         }
767 
768         default:
769         {
770 
771             /* Invalid driver request.  */
772 
773             /* Return the unhandled command status.  */
774             driver_req_ptr -> nx_ip_driver_status =  NX_UNHANDLED_COMMAND;
775         }
776     }
777 }
778 
779 
780 /**************************************************************************/
781 /*                                                                        */
782 /*  FUNCTION                                               RELEASE        */
783 /*                                                                        */
784 /*    _nx_ppp_receive_packet_get                          PORTABLE C      */
785 /*                                                           6.3.0        */
786 /*  AUTHOR                                                                */
787 /*                                                                        */
788 /*    Yuxin Zhou, Microsoft Corporation                                   */
789 /*                                                                        */
790 /*  DESCRIPTION                                                           */
791 /*                                                                        */
792 /*    This function assembles the PPP frame, which involves moving bytes  */
793 /*    from the serial buffer, converting the escape sequences, and        */
794 /*    returning the formed PPP packet to the caller.                      */
795 /*                                                                        */
796 /*  INPUT                                                                 */
797 /*                                                                        */
798 /*    ppp_ptr                               PPP instance pointer          */
799 /*    return_packet_ptr                     Return packet pointer         */
800 /*                                                                        */
801 /*  OUTPUT                                                                */
802 /*                                                                        */
803 /*    status                                Completion status             */
804 /*                                                                        */
805 /*  CALLS                                                                 */
806 /*                                                                        */
807 /*    _nx_ppp_check_crc                     Check HDLC frame CRC          */
808 /*    nx_packet_allocate                    Allocate packet               */
809 /*    nx_packet_release                     Release packet                */
810 /*                                                                        */
811 /*  CALLED BY                                                             */
812 /*                                                                        */
813 /*    ThreadX                                                             */
814 /*                                                                        */
815 /*  RELEASE HISTORY                                                       */
816 /*                                                                        */
817 /*    DATE              NAME                      DESCRIPTION             */
818 /*                                                                        */
819 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
820 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
821 /*                                            resulting in version 6.1    */
822 /*  10-31-2023     Wenhui Xie               Modified comment(s), and      */
823 /*                                            supported processing        */
824 /*                                            compressed data,            */
825 /*                                            resulting in version 6.3.0  */
826 /*                                                                        */
827 /**************************************************************************/
_nx_ppp_receive_packet_get(NX_PPP * ppp_ptr,NX_PACKET ** return_packet_ptr)828 void  _nx_ppp_receive_packet_get(NX_PPP *ppp_ptr, NX_PACKET **return_packet_ptr)
829 {
830 
831 TX_INTERRUPT_SAVE_AREA
832 NX_PACKET   *packet_head_ptr;
833 #ifndef NX_DISABLE_PACKET_CHAIN
834 NX_PACKET   *next_packet_ptr;
835 #endif
836 UCHAR       byte;
837 UCHAR       *buffer_ptr;
838 ULONG       buffer_size;
839 ULONG       timeouts;
840 NX_PACKET   *packet_ptr;
841 UINT        status;
842 
843 
844     /* Default the return packet pointer NULL.  */
845     *return_packet_ptr =  NX_NULL;
846 
847     /* Pickup the current working packet.  */
848     packet_ptr =  ppp_ptr -> nx_ppp_receive_partial_packet;
849 
850     /* Determine if there is a working receive packet.  */
851     if (packet_ptr == NX_NULL)
852     {
853 
854         /* No, setup new working receive packet.  */
855 
856         /* Allocate a packet for the PPP packet.  */
857         status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
858 
859         /* Determine if the packet was allocated successfully.  */
860         if (status != NX_SUCCESS)
861         {
862 
863 #ifndef NX_PPP_DISABLE_INFO
864 
865             /* Increment the number of packet allocation timeouts.  */
866             ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
867 #endif
868 
869             /* An error was detected, simply return a NULL pointer.  */
870             return;
871         }
872 
873         /* Save the working receive packet pointer.  */
874         ppp_ptr -> nx_ppp_receive_partial_packet =  packet_ptr;
875 
876         /* Setup the packet head pointer.  */
877         packet_head_ptr =  packet_ptr;
878         ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
879 
880         /* Setup packet payload pointer.  */
881         buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
882 
883         /* Setup packet size.  */
884         buffer_size =  0;
885 
886         /* Initialize the timeout counter.  */
887         timeouts =  0;
888     }
889     else
890     {
891 
892         /* Pickup saved buffer ptr, size and timeout counter.  */
893         buffer_ptr =   ppp_ptr -> nx_ppp_receive_buffer_ptr;
894         buffer_size =  ppp_ptr -> nx_ppp_receive_buffer_size;
895 
896         /* Pickup saved timeout count.  */
897         timeouts =  ppp_ptr -> nx_ppp_receive_timeouts;
898         /* Setup the packet head pointer.  */
899         packet_head_ptr = ppp_ptr -> nx_ppp_head_packet;
900     }
901 
902     /* Loop to drain the serial buffer.  */
903     do
904     {
905 
906         /* Disable interrupts.  */
907         TX_DISABLE
908 
909         /* Determine if there are any characters in the serial receive buffer.  */
910         if (ppp_ptr -> nx_ppp_serial_buffer_byte_count)
911         {
912 
913             /* Yes, there are one or more characters.  */
914 
915             /* Pickup the character.  */
916             byte =  ppp_ptr -> nx_ppp_serial_buffer[ppp_ptr -> nx_ppp_serial_buffer_read_index];
917 
918             /* Now determine if there is an escape sequence character and we don't have the following
919                character.  */
920             if ((byte == 0x7d) && (ppp_ptr -> nx_ppp_serial_buffer_byte_count == 1))
921             {
922 
923                 /* Restore interrupts.  */
924                 TX_RESTORE
925 
926                 /* We need to wait for another character.  */
927                 break;
928             }
929         }
930         else
931         {
932 
933             /* Nothing is left in the buffer.  */
934 
935             /* Restore interrupts.  */
936             TX_RESTORE
937 
938             /* Determine if the timeout count has been exceeded.  */
939             if (timeouts > NX_PPP_RECEIVE_TIMEOUTS)
940             {
941 
942                 /* Timeout count has been exceeded.  */
943 
944                 /* Determine if the packet is non-PPP. If so, we should dispatch it to
945                    the non-PPP packet handler.  */
946                 if ((buffer_size) && (packet_head_ptr -> nx_packet_prepend_ptr[0] != 0x7e))
947                 {
948 
949                     /* Determine if there is a user handler for non-PPP packets.  */
950                     if (ppp_ptr -> nx_ppp_non_ppp_packet_handler)
951                     {
952 
953                         /* Adjust the packet parameters.  */
954                         packet_head_ptr -> nx_packet_length =  buffer_size;
955                         packet_ptr -> nx_packet_append_ptr =  buffer_ptr;
956 
957                         /* Dispatch packet to user's handler for non-PPP packets.  */
958                         (ppp_ptr -> nx_ppp_non_ppp_packet_handler)(packet_head_ptr);
959                     }
960                     else
961                     {
962 
963                         /* Release the current packet.  */
964                         nx_packet_release(packet_head_ptr);
965                     }
966                 }
967                 else
968                 {
969 
970 #ifndef NX_PPP_DISABLE_INFO
971 
972                     /* Increment the frame timeout counter.  */
973                     ppp_ptr -> nx_ppp_frame_timeouts++;
974 #endif
975 
976                     /* Release the current packet.  */
977                     nx_packet_release(packet_head_ptr);
978                 }
979 
980                 /* Clear the saved receive packet.  */
981                 ppp_ptr -> nx_ppp_receive_partial_packet =  NX_NULL;
982 
983                 /* Allocate a packet for the PPP packet.  */
984                 status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
985 
986                 /* Determine if the packet was allocated successfully.  */
987                 if (status != NX_SUCCESS)
988                 {
989 
990 #ifndef NX_PPP_DISABLE_INFO
991 
992                     /* Increment the number of packet allocation timeouts.  */
993                     ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
994 #endif
995 
996                     /* An error was detected, simply return a NULL pointer.  */
997                     return;
998                 }
999 
1000                 /* Save the new receive packet.  */
1001                 ppp_ptr -> nx_ppp_receive_partial_packet =  packet_ptr;
1002 
1003                 /* Setup the packet head pointer.  */
1004                 packet_head_ptr =  packet_ptr;
1005                 ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
1006 
1007                 /* Setup packet payload pointer.  */
1008                 buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1009 
1010                 /* Setup packet size.  */
1011                 buffer_size =  0;
1012 
1013                 /* Initialize the timeout counter.  */
1014                 timeouts =  0;
1015             }
1016 
1017             /* We need to wait for another character.  */
1018             break;
1019         }
1020 
1021         /* At this point, we have a character. Adjust the serial buffer information.  */
1022         ppp_ptr -> nx_ppp_serial_buffer_read_index++;
1023 
1024         /* Check for serial buffer wrap-around condition.  */
1025         if (ppp_ptr -> nx_ppp_serial_buffer_read_index >= NX_PPP_SERIAL_BUFFER_SIZE)
1026         {
1027 
1028             /* Reset the buffer read index.  */
1029             ppp_ptr -> nx_ppp_serial_buffer_read_index =  0;
1030         }
1031 
1032         /* Adjust the serial buffer count.  */
1033         ppp_ptr -> nx_ppp_serial_buffer_byte_count--;
1034 
1035         /* Restore interrupts.  */
1036         TX_RESTORE
1037 
1038         /* Clear the timeouts counter.  */
1039         timeouts =  0;
1040 
1041         /* Determine if we are at the beginning of the packet.  */
1042         if (buffer_size == 0)
1043         {
1044 
1045             /* Determine if we should add a PPP frame header.  */
1046             if (byte == 0xFF)
1047             {
1048 
1049                 /* Yes, a packet is present without a leading 0x7e. Simply place it in the buffer.  */
1050                 *buffer_ptr++ =  0x7e;
1051 
1052                 /* Increment the buffer size.  */
1053                 buffer_size++;
1054             }
1055         }
1056 
1057         /* Determine if we are at the end of the PPP frame.  */
1058         else if (byte == 0x7e)
1059         {
1060 
1061             /* Yes, we are at the end of the PPP frame.  */
1062 
1063             /* Determine if a non-PPP frame preceded this end of frame marker.  */
1064             if (packet_head_ptr -> nx_packet_prepend_ptr[0] != 0x7e)
1065             {
1066 
1067                 /* Determine if there is a handler for non-PPP packets.  */
1068                 if (ppp_ptr -> nx_ppp_non_ppp_packet_handler)
1069                 {
1070 
1071                     /* Adjust the packet parameters.  */
1072                     packet_head_ptr -> nx_packet_length =  buffer_size;
1073                     packet_ptr -> nx_packet_append_ptr =  buffer_ptr;
1074 
1075                     /* Dispatch packet to user's handler for non-PPP packets.  */
1076                     (ppp_ptr -> nx_ppp_non_ppp_packet_handler)(packet_head_ptr);
1077                 }
1078                 else
1079                 {
1080 
1081                     /* Release the current packet.  */
1082                     nx_packet_release(packet_head_ptr);
1083                 }
1084 
1085                 /* Clear the saved receive packet.  */
1086                 ppp_ptr -> nx_ppp_receive_partial_packet =  NX_NULL;
1087 
1088                 /* Allocate a packet for the PPP packet.  */
1089                 status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
1090 
1091                 /* Determine if the packet was allocated successfully.  */
1092                 if (status != NX_SUCCESS)
1093                 {
1094 
1095 #ifndef NX_PPP_DISABLE_INFO
1096 
1097                     /* Increment the number of packet allocation timeouts.  */
1098                     ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
1099 #endif
1100 
1101                     /* An error was detected, simply return a NULL pointer.  */
1102                     return;
1103                 }
1104 
1105                 /* Save the current receive packet.  */
1106                 ppp_ptr -> nx_ppp_receive_partial_packet =  packet_ptr;
1107 
1108                 /* Setup the packet head pointer.  */
1109                 packet_head_ptr =  packet_ptr;
1110                 ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
1111 
1112                 /* Setup packet payload pointer.  */
1113                 buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1114 
1115                 /* Setup packet size.  */
1116                 buffer_size =  0;
1117 
1118                 /* Initialize the timeout counter.  */
1119                 timeouts =  0;
1120 
1121                 /* Continue to get the next byte.  */
1122                 continue;
1123             }
1124 
1125             /* A PPP frame is present. Put the 0x7e into the frame.  */
1126 
1127             /* Yes, place the final 0x7e in the buffer.  */
1128             *buffer_ptr++ =  0x7e;
1129 
1130             /* Increment the buffer size.  */
1131             buffer_size++;
1132 
1133             /* Adjust the packet parameters.  */
1134             packet_head_ptr -> nx_packet_length =  buffer_size;
1135             packet_ptr -> nx_packet_append_ptr =  buffer_ptr;
1136 
1137             /* Check the CRC of the packet.  */
1138             status =  _nx_ppp_check_crc(packet_head_ptr);
1139 
1140             if (status == NX_SUCCESS)
1141             {
1142 
1143                 /* Remove the FCS (2 bytes) and Flag (1 byte).  */
1144                 packet_head_ptr -> nx_packet_length =  packet_head_ptr -> nx_packet_length - 3;
1145                 packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_append_ptr - 3;
1146 
1147 #ifndef NX_DISABLE_PACKET_CHAIN
1148                 /* Check for the condition where there is essentially no data in the last packet. */
1149                 if (packet_ptr -> nx_packet_append_ptr <= packet_ptr -> nx_packet_prepend_ptr)
1150                 {
1151                     ULONG diff = (ULONG)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_append_ptr);
1152 
1153                     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1154 
1155                     if (packet_head_ptr != packet_ptr)
1156                     {
1157 
1158 
1159                         NX_PACKET *tmp_packet_ptr = packet_head_ptr;
1160                         NX_PACKET *prev_packet_ptr = tmp_packet_ptr;
1161                         while (tmp_packet_ptr -> nx_packet_next != 0x0)
1162                         {
1163                             prev_packet_ptr = tmp_packet_ptr;
1164                             tmp_packet_ptr = tmp_packet_ptr -> nx_packet_next;
1165                         }
1166 
1167                         nx_packet_release(tmp_packet_ptr);
1168                         prev_packet_ptr -> nx_packet_next = NX_NULL;
1169                         prev_packet_ptr -> nx_packet_append_ptr -= diff;
1170                     }
1171                 }
1172 #endif  /* NX_DISABLE_PACKET_CHAIN */
1173 
1174 #ifdef NX_PPP_COMPRESSION_ENABLE
1175                 if (((UINT)(packet_head_ptr -> nx_packet_append_ptr - packet_head_ptr -> nx_packet_prepend_ptr) < 3) ||
1176                     (packet_head_ptr -> nx_packet_prepend_ptr[1] != 0xff) ||
1177                     (packet_head_ptr -> nx_packet_prepend_ptr[2] != 0x03))
1178                 {
1179 
1180                     /* Address and control fields are compressed. Remove the compressed HDLC header.  */
1181                     packet_head_ptr -> nx_packet_prepend_ptr++;
1182                     packet_head_ptr -> nx_packet_length--;
1183                 }
1184 #else
1185                 if ((UINT)(packet_head_ptr -> nx_packet_append_ptr - packet_head_ptr -> nx_packet_prepend_ptr) < 3)
1186                 {
1187                     status = NX_PPP_BAD_PACKET;
1188                 }
1189 #endif /* NX_PPP_COMPRESSION_ENABLE */
1190                 else
1191                 {
1192 
1193                     /* Remove the HDLC header.  */
1194                     packet_head_ptr -> nx_packet_prepend_ptr += 3;
1195                     packet_head_ptr -> nx_packet_length -= 3;
1196                 }
1197             }
1198             else
1199             {
1200 
1201                 /* CRC error is present, just give up on the current frame.  */
1202 
1203 #ifndef NX_PPP_DISABLE_INFO
1204 
1205                 /* Increment the frame CRC error counter.  */
1206                 ppp_ptr -> nx_ppp_frame_crc_errors++;
1207 #endif
1208             }
1209 
1210             /* Determine if there was an error.  */
1211             if (status != NX_SUCCESS)
1212             {
1213 
1214                 /* Release the current packet.  */
1215                 nx_packet_release(packet_head_ptr);
1216 
1217                 /* Clear the saved receive packet.  */
1218                 ppp_ptr -> nx_ppp_receive_partial_packet =  NX_NULL;
1219 
1220                 /* Allocate a packet for the PPP packet.  */
1221                 status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER);
1222 
1223                 /* Determine if the packet was allocated successfully.  */
1224                 if (status != NX_SUCCESS)
1225                 {
1226 
1227 #ifndef NX_PPP_DISABLE_INFO
1228 
1229                     /* Increment the number of packet allocation timeouts.  */
1230                     ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
1231 #endif
1232 
1233                     /* An error was detected, simply return a NULL pointer.  */
1234                     return;
1235                 }
1236 
1237                 /* Save the current receive packet.  */
1238                 ppp_ptr -> nx_ppp_receive_partial_packet =  packet_ptr;
1239 
1240                 /* Setup the packet head pointer.  */
1241                 packet_head_ptr =  packet_ptr;
1242                 ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
1243 
1244                 /* Setup packet payload pointer.  */
1245                 buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1246 
1247                 /* Setup packet size.  */
1248                 buffer_size =  0;
1249 
1250                 /* Initialize the timeout counter.  */
1251                 timeouts =  0;
1252 
1253                 break;
1254             }
1255 
1256             /* Return the pointer.  */
1257             *return_packet_ptr =  packet_head_ptr;
1258 
1259             /* Set the receive packet to NULL to indicate there is no partial packet being
1260                processed.  */
1261             ppp_ptr -> nx_ppp_receive_partial_packet =  NX_NULL;
1262 
1263             /* Return to caller.  */
1264             return;
1265         }
1266 
1267         /* Determine if an escape byte is present.  */
1268         if (byte == 0x7d)
1269         {
1270 
1271             /* Disable interrupts.  */
1272             TX_DISABLE
1273 
1274             /* Pickup the character - we know there is one because of earlier logic.  */
1275             byte =  ppp_ptr -> nx_ppp_serial_buffer[ppp_ptr -> nx_ppp_serial_buffer_read_index++];
1276 
1277             /* Check for serial buffer wrap-around condition.  */
1278             if (ppp_ptr -> nx_ppp_serial_buffer_read_index >= NX_PPP_SERIAL_BUFFER_SIZE)
1279             {
1280 
1281                 /* Reset the buffer read index.  */
1282                 ppp_ptr -> nx_ppp_serial_buffer_read_index =  0;
1283             }
1284 
1285             /* Adjust the serial buffer count.  */
1286             ppp_ptr -> nx_ppp_serial_buffer_byte_count--;
1287 
1288             /* Restore interrupts.  */
1289             TX_RESTORE
1290 
1291             /* Convert the escape sequence character.  */
1292             byte =  byte ^ 0x20;
1293         }
1294 
1295         /* Determine if there is room in the payload.  */
1296         if (buffer_ptr < (packet_ptr -> nx_packet_data_end - 4))
1297         {
1298 
1299             /* Put the character in the packet payload.  */
1300             *buffer_ptr++ =  byte;
1301 
1302             /* Increment the buffer size.  */
1303             buffer_size++;
1304         }
1305 
1306 #ifndef NX_DISABLE_PACKET_CHAIN
1307 
1308         /* We need to perform packet chaining at this point, but only for IP data frames. Non PPP data and
1309            the other PPP protocol packets must fit within the payload of one packet.  */
1310         else if (((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
1311                   (packet_head_ptr -> nx_packet_prepend_ptr[1] == 0xff) &&
1312                   (packet_head_ptr -> nx_packet_prepend_ptr[2] == 0x03) &&
1313                   (packet_head_ptr -> nx_packet_prepend_ptr[3] == 0x00) &&
1314                   (packet_head_ptr -> nx_packet_prepend_ptr[4] == 0x21)) /* 0x0021 is NX_PPP_DATA */
1315 #ifdef NX_PPP_COMPRESSION_ENABLE
1316               || ((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
1317                   (packet_head_ptr -> nx_packet_prepend_ptr[1] == 0xff) &&
1318                   (packet_head_ptr -> nx_packet_prepend_ptr[2] == 0x03) &&
1319                   (packet_head_ptr -> nx_packet_prepend_ptr[3] == 0x21)) /* Protocol field is compressed */
1320               || ((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
1321                   (packet_head_ptr -> nx_packet_prepend_ptr[1] == 0x00) &&
1322                   (packet_head_ptr -> nx_packet_prepend_ptr[2] == 0x21)) /* Address and Control fields are compressed */
1323               || ((packet_head_ptr -> nx_packet_prepend_ptr[0] == 0x7e) &&
1324                   (packet_head_ptr -> nx_packet_prepend_ptr[1] == 0x21)) /* Protocol, Address and Control fields are compressed */
1325 #endif /* NX_PPP_COMPRESSION_ENABLE */
1326                  )
1327         {
1328 
1329             /* We need to move to the next packet and chain them.  */
1330             packet_ptr -> nx_packet_append_ptr =  buffer_ptr;
1331 
1332             /* Allocate a new packet to for packet chaining.  */
1333             status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &next_packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
1334 
1335             /* Determine if the packet was allocated successfully.  */
1336             if (status != NX_SUCCESS)
1337             {
1338 
1339 #ifndef NX_PPP_DISABLE_INFO
1340 
1341                 /* Increment the number of packet allocation timeouts.  */
1342                 ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
1343 #endif
1344 
1345                 /* Clear the partial receive packet pointer.  */
1346                 ppp_ptr -> nx_ppp_receive_partial_packet =  NX_NULL;
1347 
1348                 /* Release the current packet.  */
1349                 nx_packet_release(packet_head_ptr);
1350 
1351                 /* An error was detected, simply return a NULL pointer.  */
1352                 return;
1353             }
1354 
1355             /* Adjust the next packet pointer.  */
1356             packet_ptr -> nx_packet_next =  next_packet_ptr;
1357 
1358             /* Setup the last pointer.  */
1359             packet_head_ptr -> nx_packet_last =  next_packet_ptr;
1360 
1361             /* Use the packet pointer.  */
1362             packet_ptr =  next_packet_ptr;
1363             ppp_ptr -> nx_ppp_receive_partial_packet = packet_ptr;
1364 
1365             /* Setup buffer pointer.  */
1366             buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1367 
1368             /* Put the character in the packet payload.  */
1369             *buffer_ptr++ =  byte;
1370 
1371             /* Increment the buffer size.  */
1372             buffer_size++;
1373         }
1374 #endif /* NX_DISABLE_PACKET_CHAIN */
1375         else
1376         {
1377 
1378             /* At this point we know we have a buffer full of non-PPP characters, in
1379                most cases this is simply noise.  */
1380 
1381             /* Determine if there is a non-PPP handler.  */
1382             if (ppp_ptr -> nx_ppp_non_ppp_packet_handler)
1383             {
1384 
1385                 /* Adjust the packet parameters.  */
1386                 packet_head_ptr -> nx_packet_length =  buffer_size;
1387                 packet_ptr -> nx_packet_append_ptr =  buffer_ptr;
1388 
1389                 /* Dispatch packet to user's handler for non-PPP packets.  */
1390                 (ppp_ptr -> nx_ppp_non_ppp_packet_handler)(packet_head_ptr);
1391             }
1392             else
1393             {
1394 
1395                 /* Release the current packet.  */
1396                 nx_packet_release(packet_head_ptr);
1397             }
1398 
1399             /* Clear the partial receive packet pointer.  */
1400             ppp_ptr -> nx_ppp_receive_partial_packet =  NX_NULL;
1401 
1402             /* Allocate a packet for the PPP packet.  */
1403             status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_RECEIVE_PACKET, NX_PPP_TIMEOUT);
1404 
1405             /* Determine if the packet was allocated successfully.  */
1406             if (status != NX_SUCCESS)
1407             {
1408 
1409 #ifndef NX_PPP_DISABLE_INFO
1410 
1411                 /* Increment the number of packet allocation timeouts.  */
1412                 ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
1413 #endif
1414 
1415                 /* An error was detected, simply return a NULL pointer.  */
1416                 return;
1417             }
1418 
1419             /* Save the current receive packet.  */
1420             ppp_ptr -> nx_ppp_receive_partial_packet =  packet_ptr;
1421 
1422             /* Setup the packet head pointer.  */
1423             packet_head_ptr =  packet_ptr;
1424             ppp_ptr -> nx_ppp_head_packet = packet_head_ptr;
1425 
1426             /* Setup packet payload pointer.  */
1427             buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
1428 
1429             /* Setup packet size.  */
1430             buffer_size =  0;
1431 
1432             /* Initialize the timeout counter.  */
1433             timeouts =  0;
1434         }
1435     } while(ppp_ptr -> nx_ppp_serial_buffer_byte_count);
1436 
1437     /* Save the buffer size, buffer pointer, and timeout count.  */
1438     ppp_ptr -> nx_ppp_receive_buffer_size =  buffer_size;
1439     ppp_ptr -> nx_ppp_receive_buffer_ptr =   buffer_ptr;
1440     ppp_ptr -> nx_ppp_receive_timeouts =     timeouts;
1441 }
1442 
1443 
1444 /**************************************************************************/
1445 /*                                                                        */
1446 /*  FUNCTION                                               RELEASE        */
1447 /*                                                                        */
1448 /*    _nx_ppp_receive_packet_process                      PORTABLE C      */
1449 /*                                                           6.3.0        */
1450 /*  AUTHOR                                                                */
1451 /*                                                                        */
1452 /*    Yuxin Zhou, Microsoft Corporation                                   */
1453 /*                                                                        */
1454 /*  DESCRIPTION                                                           */
1455 /*                                                                        */
1456 /*    This function processes a received PPP request and dispatches it    */
1457 /*    to the appropriate protocol or to NetX.                             */
1458 /*                                                                        */
1459 /*  INPUT                                                                 */
1460 /*                                                                        */
1461 /*    ppp_ptr                               PPP instance pointer          */
1462 /*    packet_ptr                            Pointer to PPP packet         */
1463 /*                                                                        */
1464 /*  OUTPUT                                                                */
1465 /*                                                                        */
1466 /*    status                                Completion status             */
1467 /*                                                                        */
1468 /*  CALLS                                                                 */
1469 /*                                                                        */
1470 /*    nx_packet_release                     Release packet                */
1471 /*    _nx_ppp_lcp_state_machine_update      Process LCP message           */
1472 /*    _nx_ppp_pap_state_machine_update      Process PAP message           */
1473 /*    _nx_ppp_chap_state_machine_update     Process CHAP message          */
1474 /*    _nx_ppp_ipcp_state_machine_update     Process IPCP message          */
1475 /*    _nx_ppp_netx_packet_transfer          Transfer packet to NetX       */
1476 /*                                                                        */
1477 /*  CALLED BY                                                             */
1478 /*                                                                        */
1479 /*    _nx_ppp_thread_entry                  PPP thread entry              */
1480 /*                                                                        */
1481 /*  RELEASE HISTORY                                                       */
1482 /*                                                                        */
1483 /*    DATE              NAME                      DESCRIPTION             */
1484 /*                                                                        */
1485 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1486 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1487 /*                                            resulting in version 6.1    */
1488 /*  11-09-2020     Yuxin Zhou               Modified comment(s),          */
1489 /*                                            improved packet length      */
1490 /*                                            verification,               */
1491 /*                                            resulting in version 6.1.2  */
1492 /*  10-31-2023     Wenhui Xie               Modified comment(s), and      */
1493 /*                                            supported processing        */
1494 /*                                            compressed data,            */
1495 /*                                            resulting in version 6.3.0  */
1496 /*                                                                        */
1497 /**************************************************************************/
_nx_ppp_receive_packet_process(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)1498 void  _nx_ppp_receive_packet_process(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
1499 {
1500 
1501 UINT        protocol;
1502 UINT        ppp_ipcp_state;
1503 UINT        code;
1504 UINT        length;
1505 
1506 
1507 #ifndef NX_PPP_DISABLE_INFO
1508 
1509     /* Increment the number of IP frames sent.  */
1510     ppp_ptr -> nx_ppp_total_frames_received++;
1511 #endif
1512 
1513 #ifdef NX_PPP_COMPRESSION_ENABLE
1514 
1515     /* Check for valid packet length for Protocol (if compressed, it should be 1 byte).  */
1516     if (packet_ptr -> nx_packet_length < 1)
1517 #else
1518 
1519     /* Check for valid packet length for Protocol (2 bytes).  */
1520     if (packet_ptr -> nx_packet_length < 2)
1521 #endif /* NX_PPP_COMPRESSION_ENABLE */
1522     {
1523 
1524         /* Release the packet. */
1525         nx_packet_release(packet_ptr);
1526 
1527         /* Return.  */
1528         return;
1529     }
1530 
1531 #ifdef NX_PPP_COMPRESSION_ENABLE
1532 
1533     /* Pickup the protocol type.  */
1534     if (packet_ptr -> nx_packet_prepend_ptr[0] & NX_PPP_PROTOCOL_LSB_MARK)
1535     {
1536 
1537         /* The protocol field is compressed to 1 byte.  */
1538         protocol =  (UINT) packet_ptr -> nx_packet_prepend_ptr[0];
1539     }
1540     else
1541 #endif /* NX_PPP_COMPRESSION_ENABLE */
1542     {
1543 
1544         /* The protocol field is 2 bytes.  */
1545         protocol =  (((UINT) packet_ptr -> nx_packet_prepend_ptr[0]) << 8) | ((UINT) packet_ptr -> nx_packet_prepend_ptr[1]);
1546     }
1547 
1548     /* Check protocol.  */
1549     if (protocol != NX_PPP_DATA)
1550     {
1551 
1552 #ifndef NX_DISABLE_PACKET_CHAIN
1553 
1554         /* Discard the chained packets.  */
1555         if (packet_ptr -> nx_packet_next)
1556         {
1557 
1558             /* Release the packet. */
1559             nx_packet_release(packet_ptr);
1560 
1561             /* Return.  */
1562             return;
1563         }
1564 #endif
1565 
1566         /* Other Protocols must also have Code:1 byte, Identifier:1 bytes, Length: 2 bytes.  */
1567         if (packet_ptr -> nx_packet_length < 6)
1568         {
1569 
1570             /* Release the packet. */
1571             nx_packet_release(packet_ptr);
1572 
1573             /* Return.  */
1574             return;
1575         }
1576 
1577         /* Get the message length.  */
1578         length = (((UINT) packet_ptr -> nx_packet_prepend_ptr[4]) << 8) | ((UINT) packet_ptr -> nx_packet_prepend_ptr[5]);
1579 
1580         /* Check if the packet length is equal to message length plus 2 bytes protocal type.  */
1581         if ((length + 2) != packet_ptr -> nx_packet_length)
1582         {
1583 
1584             /* Release the packet. */
1585             nx_packet_release(packet_ptr);
1586 
1587             /* Return.  */
1588             return;
1589         }
1590     }
1591 
1592     /* Determine if the packet is LCP.  */
1593     if (protocol == NX_PPP_LCP_PROTOCOL)
1594     {
1595 
1596         /* Pickup the type of received LCP code.  */
1597         code =  packet_ptr -> nx_packet_prepend_ptr[2];
1598 
1599         /* Process the LCP message, updating the LCP state machine.  */
1600         _nx_ppp_lcp_state_machine_update(ppp_ptr, packet_ptr);
1601 
1602         /* Determine if the LCP is now complete.  */
1603         if (ppp_ptr -> nx_ppp_lcp_state ==  NX_PPP_LCP_COMPLETED_STATE)
1604         {
1605 
1606 #ifndef NX_PPP_DISABLE_PAP
1607 
1608             /* Determine if the PAP state machine should be started. */
1609             if ((ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_PAP_PROTOCOL) ||
1610                 (ppp_ptr -> nx_ppp_verify_authentication_protocol == NX_PPP_PAP_PROTOCOL))
1611             {
1612 
1613                 /* Check if PAP already start.  */
1614                 if (ppp_ptr -> nx_ppp_pap_state == NX_PPP_PAP_INITIAL_STATE)
1615                 {
1616 
1617                     /* Yes, change state to PAP start state and update the PAP state machine.  */
1618                     ppp_ptr -> nx_ppp_pap_state = NX_PPP_PAP_START_STATE;
1619 
1620                     /* Process the PAP message.  */
1621                     _nx_ppp_pap_state_machine_update(ppp_ptr, NX_NULL);
1622                 }
1623             }
1624 #endif
1625 
1626 #ifndef NX_PPP_DISABLE_CHAP
1627 
1628             /* Determine if the CHAP state machine should be started. */
1629             if ((ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_CHAP_PROTOCOL) ||
1630                 (ppp_ptr -> nx_ppp_verify_authentication_protocol == NX_PPP_CHAP_PROTOCOL))
1631             {
1632 
1633                 /* Check if CHAP already start.  */
1634                 if (ppp_ptr -> nx_ppp_chap_state == NX_PPP_CHAP_INITIAL_STATE)
1635                 {
1636 
1637                     /* Yes, change state to CHAP start state and update the CHAP state machine.  */
1638                     ppp_ptr -> nx_ppp_chap_state = NX_PPP_CHAP_START_STATE;
1639 
1640                     /* Process the CHAP message.  */
1641                     _nx_ppp_chap_state_machine_update(ppp_ptr, NX_NULL);
1642                 }
1643             }
1644 #endif
1645 
1646             /* Do not set the IPCP state to INIT on receipt of an LCP echo request or reply! */
1647             if ((code != NX_PPP_LCP_ECHO_REQUEST) && (code != NX_PPP_LCP_ECHO_REPLY))
1648             {
1649 
1650                 /* Check for authentication.  */
1651                 if (ppp_ptr -> nx_ppp_authenticated)
1652                 {
1653 
1654                     /* Check if IPCP already start.  */
1655                     if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_INITIAL_STATE)
1656                     {
1657 
1658                         /* Yes, change state to IPCP start state and update the PAP state machine.  */
1659                         ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_START_STATE;
1660 
1661                         /* Process the IPCP message.  */
1662                         _nx_ppp_ipcp_state_machine_update(ppp_ptr, NX_NULL);
1663                     }
1664                 }
1665             }
1666 
1667             /* Check if the packet is Echo Request.  */
1668             if (code == NX_PPP_LCP_ECHO_REQUEST)
1669             {
1670 
1671                 /* Clear the pointer since it was sent out as Echo Reply.  */
1672                 packet_ptr =  NX_NULL;
1673             }
1674         }
1675     }
1676 
1677 
1678 #ifndef NX_PPP_DISABLE_PAP
1679 
1680     /* Determine if the packet is PAP.  */
1681     else if (protocol == NX_PPP_PAP_PROTOCOL)
1682     {
1683 
1684         /* Process the PAP message.  */
1685         _nx_ppp_pap_state_machine_update(ppp_ptr, packet_ptr);
1686 
1687         /* Check for authentication.  */
1688         if (ppp_ptr -> nx_ppp_authenticated)
1689         {
1690 
1691             /* Check if IPCP already start.  */
1692             if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_INITIAL_STATE)
1693             {
1694 
1695                 /* Yes, change state to IPCP start state and update the IPCP state machine.  */
1696                 ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_START_STATE;
1697 
1698                 /* Process the IPCP message.  */
1699                 _nx_ppp_ipcp_state_machine_update(ppp_ptr, NX_NULL);
1700             }
1701         }
1702     }
1703 #endif
1704 
1705 #ifndef NX_PPP_DISABLE_CHAP
1706 
1707     /* Determine if the packet is CHAP.  */
1708     else if (protocol == NX_PPP_CHAP_PROTOCOL)
1709     {
1710 
1711         /* Process the CHAP message.  */
1712         _nx_ppp_chap_state_machine_update(ppp_ptr, packet_ptr);
1713 
1714         /* Check for authentication.  */
1715         if (ppp_ptr -> nx_ppp_authenticated)
1716         {
1717 
1718             /* Check if IPCP already start.  */
1719             if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_INITIAL_STATE)
1720             {
1721 
1722                 /* Yes, change state to IPCP start state and update the IPCP state machine.  */
1723                 ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_START_STATE;
1724 
1725                 /* Process the IPCP message.  */
1726                 _nx_ppp_ipcp_state_machine_update(ppp_ptr, NX_NULL);
1727             }
1728         }
1729     }
1730 #endif
1731 
1732     /* Determine if packet is IPCP.  */
1733     else if (protocol == NX_PPP_IPCP_PROTOCOL)
1734     {
1735 
1736         /* Process the IPCP message.  */
1737         ppp_ipcp_state = ppp_ptr -> nx_ppp_ipcp_state;
1738 
1739         _nx_ppp_ipcp_state_machine_update(ppp_ptr, packet_ptr);
1740 
1741         /* Check for IPCP completion... when this happens, the link is up!  */
1742         if (ppp_ptr -> nx_ppp_ipcp_state ==  NX_PPP_IPCP_COMPLETED_STATE)
1743         {
1744 
1745             /* Set the PPP state machine to indicate it is complete.  */
1746             ppp_ptr -> nx_ppp_state =  NX_PPP_ESTABLISHED;
1747 
1748             /* Mark the IP interface instance as link up.  */
1749             (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_link_up =  NX_TRUE;
1750 
1751             /* Determine if the application has registered a link up notification
1752                callback.  */
1753             if ((ppp_ptr -> nx_ppp_link_up_callback) && (ppp_ipcp_state!=NX_PPP_IPCP_COMPLETED_STATE))
1754             {
1755 
1756                 /* Yes, call the application's callback function.  */
1757                 (ppp_ptr -> nx_ppp_link_up_callback)(ppp_ptr);
1758             }
1759         }
1760     }
1761 
1762     /* Check for normal data packet.  */
1763     else if (protocol == NX_PPP_DATA)
1764     {
1765 
1766         /* Transfer the packet to NetX.  */
1767         _nx_ppp_netx_packet_transfer(ppp_ptr, packet_ptr);
1768 
1769         /* Clear the pointer since it was passed to NetX.  */
1770         packet_ptr =  NX_NULL;
1771     }
1772 #ifndef NX_PPP_DISABLE_INFO
1773 
1774     else
1775         /* Increment the number of frames dropped.  */
1776         ppp_ptr -> nx_ppp_receive_frames_dropped++;
1777 #endif
1778 
1779     /* Determine if the packet needs to be released.  */
1780     if (packet_ptr)
1781     {
1782 
1783         /* Release the packet.  */
1784         nx_packet_release(packet_ptr);
1785     }
1786 }
1787 
1788 
1789 /**************************************************************************/
1790 /*                                                                        */
1791 /*  FUNCTION                                               RELEASE        */
1792 /*                                                                        */
1793 /*    _nx_ppp_timeout                                     PORTABLE C      */
1794 /*                                                           6.1          */
1795 /*  AUTHOR                                                                */
1796 /*                                                                        */
1797 /*    Yuxin Zhou, Microsoft Corporation                                   */
1798 /*                                                                        */
1799 /*  DESCRIPTION                                                           */
1800 /*                                                                        */
1801 /*    This function processes PPP time-out events, which includes         */
1802 /*    updating the responsible state machine.                             */
1803 /*                                                                        */
1804 /*  INPUT                                                                 */
1805 /*                                                                        */
1806 /*    ppp_ptr                               PPP instance pointer          */
1807 /*                                                                        */
1808 /*  OUTPUT                                                                */
1809 /*                                                                        */
1810 /*    None                                                                */
1811 /*                                                                        */
1812 /*  CALLS                                                                 */
1813 /*                                                                        */
1814 /*    _nx_ppp_lcp_state_machine_update      PPP state machine update      */
1815 /*    _nx_ppp_pap_state_machine_update      PPP PAP state machine update  */
1816 /*    _nx_ppp_chap_state_machine_update     PPP CHAP state machine update */
1817 /*    _nx_ppp_ipcp_state_machine_update     PPP IPCP state machine update */
1818 /*                                                                        */
1819 /*  CALLED BY                                                             */
1820 /*                                                                        */
1821 /*    ThreadX                                                             */
1822 /*                                                                        */
1823 /*  RELEASE HISTORY                                                       */
1824 /*                                                                        */
1825 /*    DATE              NAME                      DESCRIPTION             */
1826 /*                                                                        */
1827 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1828 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1829 /*                                            resulting in version 6.1    */
1830 /*                                                                        */
1831 /**************************************************************************/
_nx_ppp_timeout(NX_PPP * ppp_ptr)1832 void _nx_ppp_timeout(NX_PPP *ppp_ptr)
1833 {
1834 
1835     /* Determine if the LCP state machine needs updating.  */
1836     if ((ppp_ptr -> nx_ppp_lcp_state >= NX_PPP_LCP_START_STATE) &&
1837          (ppp_ptr -> nx_ppp_lcp_state < NX_PPP_LCP_COMPLETED_STATE))
1838     {
1839 
1840         /* Update the PPP state machine.  */
1841         _nx_ppp_lcp_state_machine_update(ppp_ptr, NX_NULL);
1842     }
1843 
1844 #ifndef NX_PPP_DISABLE_PAP
1845 
1846     /* Determine if the PAP state machine needs updating.  */
1847     if ((ppp_ptr -> nx_ppp_pap_state >= NX_PPP_PAP_START_STATE) &&
1848          (ppp_ptr -> nx_ppp_pap_state < NX_PPP_PAP_COMPLETED_STATE))
1849     {
1850 
1851          /* Update the PAP state machine.  */
1852          _nx_ppp_pap_state_machine_update(ppp_ptr, NX_NULL);
1853     }
1854 #endif
1855 
1856 #ifndef NX_PPP_DISABLE_CHAP
1857 
1858     /* Determine if the CHAP state machine needs updating.  */
1859     if ((ppp_ptr -> nx_ppp_chap_state >= NX_PPP_CHAP_START_STATE) &&
1860          (ppp_ptr -> nx_ppp_chap_state < NX_PPP_CHAP_COMPLETED_STATE))
1861     {
1862 
1863          /* Update the CHAP state machine.  */
1864          _nx_ppp_chap_state_machine_update(ppp_ptr, NX_NULL);
1865     }
1866 #endif
1867 
1868     /* Determine if the IPCP state machine needs updating.  */
1869     if ((ppp_ptr -> nx_ppp_ipcp_state >= NX_PPP_IPCP_START_STATE) &&
1870          (ppp_ptr -> nx_ppp_ipcp_state < NX_PPP_IPCP_COMPLETED_STATE))
1871     {
1872 
1873         /* Update the IPCP state machine.  */
1874         _nx_ppp_ipcp_state_machine_update(ppp_ptr, NX_NULL);
1875     }
1876 }
1877 
1878 
1879 /**************************************************************************/
1880 /*                                                                        */
1881 /*  FUNCTION                                               RELEASE        */
1882 /*                                                                        */
1883 /*    _nx_ppp_timer_entry                                 PORTABLE C      */
1884 /*                                                           6.1          */
1885 /*  AUTHOR                                                                */
1886 /*                                                                        */
1887 /*    Yuxin Zhou, Microsoft Corporation                                   */
1888 /*                                                                        */
1889 /*  DESCRIPTION                                                           */
1890 /*                                                                        */
1891 /*    This function processes PPP time-outs, which sets a time-out event  */
1892 /*    that wakes up the PPP processing thread.                            */
1893 /*                                                                        */
1894 /*  INPUT                                                                 */
1895 /*                                                                        */
1896 /*    ppp_ptr                               PPP instance pointer          */
1897 /*                                                                        */
1898 /*  OUTPUT                                                                */
1899 /*                                                                        */
1900 /*    None                                                                */
1901 /*                                                                        */
1902 /*  CALLS                                                                 */
1903 /*                                                                        */
1904 /*    tx_event_flags_set                    Set timeout event flag        */
1905 /*                                                                        */
1906 /*  CALLED BY                                                             */
1907 /*                                                                        */
1908 /*    ThreadX                                                             */
1909 /*                                                                        */
1910 /*  RELEASE HISTORY                                                       */
1911 /*                                                                        */
1912 /*    DATE              NAME                      DESCRIPTION             */
1913 /*                                                                        */
1914 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1915 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1916 /*                                            resulting in version 6.1    */
1917 /*                                                                        */
1918 /**************************************************************************/
_nx_ppp_timer_entry(ULONG id)1919 void _nx_ppp_timer_entry(ULONG id)
1920 {
1921 
1922 NX_PPP  *ppp_ptr;
1923 
1924 
1925     /* Pickup the PPP pointer.  */
1926     ppp_ptr =  (NX_PPP *) id;
1927 
1928     /* Make sure the PPP pointer is good.  */
1929     if ((ppp_ptr != NX_NULL) && (ppp_ptr -> nx_ppp_id == NX_PPP_ID))
1930     {
1931 
1932         /* Set the timeout event for the PPP thread.  */
1933         tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_TIMEOUT, TX_OR);
1934     }
1935 }
1936 
1937 
1938 /**************************************************************************/
1939 /*                                                                        */
1940 /*  FUNCTION                                               RELEASE        */
1941 /*                                                                        */
1942 /*    _nx_ppp_netx_packet_transfer                        PORTABLE C      */
1943 /*                                                           6.3.0        */
1944 /*  AUTHOR                                                                */
1945 /*                                                                        */
1946 /*    Yuxin Zhou, Microsoft Corporation                                   */
1947 /*                                                                        */
1948 /*  DESCRIPTION                                                           */
1949 /*                                                                        */
1950 /*    This function removes the PPP header and passes the packet to       */
1951 /*    NetX.                                                               */
1952 /*                                                                        */
1953 /*  INPUT                                                                 */
1954 /*                                                                        */
1955 /*    ppp_ptr                               Pointer to PPP instance       */
1956 /*                                                                        */
1957 /*  OUTPUT                                                                */
1958 /*                                                                        */
1959 /*    None                                                                */
1960 /*                                                                        */
1961 /*  CALLS                                                                 */
1962 /*                                                                        */
1963 /*    _nx_ip_packet_deferred_receive        Deferred IP packet receive    */
1964 /*    _nx_ip_packet_receive                 IP packet receive             */
1965 /*                                                                        */
1966 /*  CALLED BY                                                             */
1967 /*                                                                        */
1968 /*    _nx_ppp_receive_packet_process        Receive packet processing     */
1969 /*                                                                        */
1970 /*  RELEASE HISTORY                                                       */
1971 /*                                                                        */
1972 /*    DATE              NAME                      DESCRIPTION             */
1973 /*                                                                        */
1974 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1975 /*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
1976 /*                                            verified memmove use cases, */
1977 /*                                            resulting in version 6.1    */
1978 /*  10-31-2023     Wenhui Xie               Modified comment(s), and      */
1979 /*                                            supported processing        */
1980 /*                                            compressed data,            */
1981 /*                                            resulting in version 6.3.0  */
1982 /*                                                                        */
1983 /**************************************************************************/
_nx_ppp_netx_packet_transfer(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)1984 void _nx_ppp_netx_packet_transfer(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
1985 {
1986 
1987 ULONG   offset;
1988 
1989 #ifndef NX_PPP_DISABLE_INFO
1990     /* Increment the number of IP frames received.  */
1991     ppp_ptr -> nx_ppp_ip_frames_received++;
1992 #endif
1993 
1994     /* Add the incoming interface pointer.  */
1995     packet_ptr -> nx_packet_ip_interface =  ppp_ptr -> nx_ppp_interface_ptr;
1996 
1997 #ifdef NX_PPP_COMPRESSION_ENABLE
1998 
1999     /* Check whether the protocol field is 1 byte or 2 bytes.  */
2000     if (packet_ptr -> nx_packet_prepend_ptr[0] & NX_PPP_PROTOCOL_LSB_MARK)
2001     {
2002 
2003         /* Remove the PPP header [21] in the front of the IP packet.  */
2004         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 1;
2005 
2006         /* Adjust the packet length.  */
2007         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 1;
2008 
2009     }
2010     else
2011 #endif /* NX_PPP_COMPRESSION_ENABLE */
2012     {
2013 
2014         /* Remove the PPP header [00,21] in the front of the IP packet.  */
2015         packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_prepend_ptr + 2;
2016 
2017         /* Adjust the packet length.  */
2018         packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length - 2;
2019     }
2020 
2021     /* Calculate the offset for four byte alignment.  */
2022     offset = (((ULONG)packet_ptr -> nx_packet_prepend_ptr) & 3);
2023 
2024     /* Move the data to keep four byte alignment for first packet.  */
2025     if (offset)
2026     {
2027         memmove(packet_ptr -> nx_packet_prepend_ptr - offset, packet_ptr -> nx_packet_prepend_ptr, /* Use case of memmove is verified.  */
2028                 (UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr));
2029         packet_ptr -> nx_packet_prepend_ptr -= offset;
2030         packet_ptr -> nx_packet_append_ptr -= offset;
2031     }
2032 
2033     /* Transfer the receive packet to NetX.  */
2034 #ifdef NX_DIRECT_ISR_CALL
2035     _nx_ip_packet_receive(ppp_ptr -> nx_ppp_ip_ptr, packet_ptr);
2036 #else
2037     _nx_ip_packet_deferred_receive(ppp_ptr -> nx_ppp_ip_ptr, packet_ptr);
2038 #endif
2039 }
2040 
2041 
2042 /**************************************************************************/
2043 /*                                                                        */
2044 /*  FUNCTION                                               RELEASE        */
2045 /*                                                                        */
2046 /*    _nx_ppp_process_deferred_raw_string_send            PORTABLE C      */
2047 /*                                                           6.1          */
2048 /*  AUTHOR                                                                */
2049 /*                                                                        */
2050 /*    Yuxin Zhou, Microsoft Corporation                                   */
2051 /*                                                                        */
2052 /*  DESCRIPTION                                                           */
2053 /*                                                                        */
2054 /*    This function takes all the raw string packets from the deferred raw*/
2055 /*    string packet queue and then sends them out.                        */
2056 /*                                                                        */
2057 /*  INPUT                                                                 */
2058 /*                                                                        */
2059 /*    ppp_ptr                               PPP instance pointer          */
2060 /*                                                                        */
2061 /*  OUTPUT                                                                */
2062 /*                                                                        */
2063 /*    None                                                                */
2064 /*                                                                        */
2065 /*  CALLS                                                                 */
2066 /*                                                                        */
2067 /*    (nx_ppp_byte_send)                    User's byte output routine    */
2068 /*    nx_packet_release                     Release packet                */
2069 /*                                                                        */
2070 /*  CALLED BY                                                             */
2071 /*                                                                        */
2072 /*    _nx_ppp_thread_entry                  PPP processing thread         */
2073 /*                                                                        */
2074 /*  RELEASE HISTORY                                                       */
2075 /*                                                                        */
2076 /*    DATE              NAME                      DESCRIPTION             */
2077 /*                                                                        */
2078 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2079 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2080 /*                                            resulting in version 6.1    */
2081 /*                                                                        */
2082 /**************************************************************************/
_nx_ppp_process_deferred_raw_string_send(NX_PPP * ppp_ptr)2083 void _nx_ppp_process_deferred_raw_string_send(NX_PPP *ppp_ptr)
2084 {
2085 
2086 TX_INTERRUPT_SAVE_AREA
2087 
2088 NX_PACKET       *packet_ptr;
2089 ULONG           i;
2090 #ifdef NX_PPP_PPPOE_ENABLE
2091 UINT            release_packet;
2092 #endif /* NX_PPP_PPPOE_ENABLE  */
2093 
2094 
2095     /* Loop to process all queued packets.  */
2096     do
2097     {
2098 
2099         /* Disable interrupts.  */
2100         TX_DISABLE
2101 
2102         /* Pickup the number of queued packets.   */
2103         if (ppp_ptr -> nx_ppp_raw_packet_queue_count)
2104         {
2105 
2106             /* Pickup the oldest packet.  */
2107             packet_ptr =  ppp_ptr -> nx_ppp_raw_packet_queue_head;
2108 
2109             /* Update the head pointer to the next packet. */
2110             ppp_ptr -> nx_ppp_raw_packet_queue_head =  packet_ptr -> nx_packet_queue_next;
2111 
2112             /* Decrement the number of queued packets.  */
2113             ppp_ptr -> nx_ppp_raw_packet_queue_count--;
2114         }
2115         else
2116         {
2117 
2118             /* No packet just set the packet pointer to NULL.  */
2119             packet_ptr =  NX_NULL;
2120         }
2121 
2122         /* Restore interrupts.  */
2123         TX_RESTORE
2124 
2125         /* Is there a packet to process?  */
2126         if (packet_ptr == NX_NULL)
2127         {
2128 
2129             /* No, just get out of the loop!  */
2130             break;
2131         }
2132 
2133 #ifdef NX_PPP_PPPOE_ENABLE
2134         release_packet = NX_TRUE;
2135 #endif /* NX_PPP_PPPOE_ENABLE  */
2136 
2137         if (ppp_ptr -> nx_ppp_byte_send)
2138         {
2139 
2140             /* Loop to send all the bytes of the packet out.  */
2141             for (i = 0; i < packet_ptr -> nx_packet_length; i++)
2142             {
2143 
2144                 /* Send each byte out.  */
2145                 (ppp_ptr -> nx_ppp_byte_send)(packet_ptr -> nx_packet_prepend_ptr[i]);
2146             }
2147         }
2148 
2149 #ifdef NX_PPP_PPPOE_ENABLE
2150 
2151         /* Check the PPPoE packet send function.  */
2152         if (ppp_ptr -> nx_ppp_packet_send)
2153         {
2154 
2155             /* Send the packet out.  */
2156             (ppp_ptr -> nx_ppp_packet_send)(packet_ptr);
2157 
2158             /* Update the flag since this packet should been released in PPPoE.  */
2159             release_packet = NX_FALSE;
2160         }
2161 
2162         /* Check if need to release the packet.  */
2163         if (release_packet == NX_TRUE)
2164 #endif /* NX_PPP_PPPOE_ENABLE  */
2165 
2166             nx_packet_release(packet_ptr);
2167 
2168     } while (1);
2169 }
2170 
2171 
2172 /**************************************************************************/
2173 /*                                                                        */
2174 /*  FUNCTION                                               RELEASE        */
2175 /*                                                                        */
2176 /*    _nx_ppp_process_deferred_ip_packet_send             PORTABLE C      */
2177 /*                                                           6.1          */
2178 /*  AUTHOR                                                                */
2179 /*                                                                        */
2180 /*    Yuxin Zhou, Microsoft Corporation                                   */
2181 /*                                                                        */
2182 /*  DESCRIPTION                                                           */
2183 /*                                                                        */
2184 /*    This function takes all the packets from the deferred IP packet     */
2185 /*    queue, packages them in an PPP frame, and then sends them out.      */
2186 /*                                                                        */
2187 /*  INPUT                                                                 */
2188 /*                                                                        */
2189 /*    ppp_ptr                               PPP instance pointer          */
2190 /*                                                                        */
2191 /*  OUTPUT                                                                */
2192 /*                                                                        */
2193 /*    None                                                                */
2194 /*                                                                        */
2195 /*  CALLS                                                                 */
2196 /*                                                                        */
2197 /*    _nx_ppp_packet_transmit               Send AHDLC packet             */
2198 /*    nx_packet_transmit_release            Release NetX packet           */
2199 /*                                                                        */
2200 /*  CALLED BY                                                             */
2201 /*                                                                        */
2202 /*    _nx_ppp_thread_entry                  PPP processing thread         */
2203 /*                                                                        */
2204 /*  RELEASE HISTORY                                                       */
2205 /*                                                                        */
2206 /*    DATE              NAME                      DESCRIPTION             */
2207 /*                                                                        */
2208 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2209 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2210 /*                                            resulting in version 6.1    */
2211 /*                                                                        */
2212 /**************************************************************************/
_nx_ppp_process_deferred_ip_packet_send(NX_PPP * ppp_ptr)2213 void _nx_ppp_process_deferred_ip_packet_send(NX_PPP *ppp_ptr)
2214 {
2215 
2216 TX_INTERRUPT_SAVE_AREA
2217 
2218 NX_PACKET       *packet_ptr;
2219 
2220 
2221     /* Loop to process all queued packets.  */
2222     do
2223     {
2224 
2225         /* Disable interrupts.  */
2226         TX_DISABLE
2227 
2228         /* Pickup the number of queued packets.   */
2229         if (ppp_ptr -> nx_ppp_ip_packet_queue_count)
2230         {
2231 
2232             /* Pickup the oldest packet.  */
2233             packet_ptr =  ppp_ptr -> nx_ppp_ip_packet_queue_head;
2234 
2235             /* Update the head pointer to the next packet. */
2236             ppp_ptr -> nx_ppp_ip_packet_queue_head =  packet_ptr -> nx_packet_queue_next;
2237 
2238             /* Decrement the number of queued packets.  */
2239             ppp_ptr -> nx_ppp_ip_packet_queue_count--;
2240         }
2241         else
2242         {
2243 
2244             /* No packet just set the packet pointer to NULL.  */
2245             packet_ptr =  NX_NULL;
2246         }
2247 
2248         /* Restore interrupts.  */
2249         TX_RESTORE
2250 
2251         /* Is there a packet to process?  */
2252         if (packet_ptr == NX_NULL)
2253         {
2254 
2255             /* No, just get out of the loop!  */
2256             break;
2257         }
2258 
2259         /* Determine if there is room in the front of the packet for the PPP header.  */
2260         if ((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) < 2)
2261         {
2262 
2263             /* Error, there is no room at the front of the packet to prepend the PPP header.  */
2264 
2265 #ifndef NX_PPP_DISABLE_INFO
2266 
2267             /* Increment the internal error counter.  */
2268             ppp_ptr -> nx_ppp_internal_errors++;
2269 #endif
2270 
2271             /* Release the NetX packet.  */
2272             nx_packet_transmit_release(packet_ptr);
2273 
2274             /* An error was detected, simply return a NULL pointer.  */
2275             return;
2276         }
2277 
2278         /* Otherwise, backup the prepend pointer.  */
2279         packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_prepend_ptr - 2;
2280 
2281         /* Place the PPP header in the packet.  */
2282         packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_DATA & 0xFF00) >> 8;
2283         packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_DATA & 0xFF;
2284 
2285         /* Adjust the length of the packet.  */
2286         packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length + 2;
2287 
2288 #ifndef NX_PPP_DISABLE_INFO
2289 
2290         /* Increment the number of IP frames sent.  */
2291         ppp_ptr -> nx_ppp_ip_frames_sent++;
2292 #endif
2293 
2294         /* Send the packet!  */
2295         _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
2296     } while (1);
2297 }
2298 
2299 
2300 /**************************************************************************/
2301 /*                                                                        */
2302 /*  FUNCTION                                               RELEASE        */
2303 /*                                                                        */
2304 /*    _nx_ppp_lcp_state_machine_update                    PORTABLE C      */
2305 /*                                                           6.1.8        */
2306 /*  AUTHOR                                                                */
2307 /*                                                                        */
2308 /*    Yuxin Zhou, Microsoft Corporation                                   */
2309 /*                                                                        */
2310 /*  DESCRIPTION                                                           */
2311 /*                                                                        */
2312 /*    This function processes LCP messages and updates the LCP state      */
2313 /*    machine.                                                            */
2314 /*                                                                        */
2315 /*  INPUT                                                                 */
2316 /*                                                                        */
2317 /*    ppp_ptr                               PPP instance pointer          */
2318 /*    packet_ptr                            Pointer to LCP packet. If the */
2319 /*                                            packet is NULL, a timeout is*/
2320 /*                                            present                     */
2321 /*                                                                        */
2322 /*  OUTPUT                                                                */
2323 /*                                                                        */
2324 /*    None                                                                */
2325 /*                                                                        */
2326 /*  CALLS                                                                 */
2327 /*                                                                        */
2328 /*    _nx_ppp_lcp_code_reject               Reject received code          */
2329 /*    _nx_ppp_lcp_configuration_retrieve    Retrieve configuration info   */
2330 /*    _nx_ppp_lcp_configure_reply_send      Send configure reply          */
2331 /*    _nx_ppp_lcp_configure_request_send    Send configure request        */
2332 /*    _nx_ppp_lcp_nak_configure_list        Get options naked             */
2333 /*    _nx_ppp_lcp_terminate_ack_send        Send terminate ack            */
2334 /*    _nx_ppp_lcp_terminate_request_send    Send terminate request        */
2335 /*                                                                        */
2336 /*  CALLED BY                                                             */
2337 /*                                                                        */
2338 /*    _nx_ppp_receive_packet_process        Receive packet processing     */
2339 /*    _nx_ppp_timeout                       PPP timeout                   */
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 /*  11-09-2020     Yuxin Zhou               Modified comment(s),          */
2349 /*                                            improved packet length      */
2350 /*                                            verification,               */
2351 /*                                            resulting in version 6.1.2  */
2352 /*  08-02-2021     Yuxin Zhou               Modified comment(s), fixed    */
2353 /*                                            the logic of retransmission,*/
2354 /*                                            resulting in version 6.1.8  */
2355 /*                                                                        */
2356 /**************************************************************************/
_nx_ppp_lcp_state_machine_update(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)2357 void  _nx_ppp_lcp_state_machine_update(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
2358 {
2359 
2360 UINT    configure_status;
2361 UCHAR   *lcp_message_ptr;
2362 UCHAR   code;
2363 UINT    status;
2364 
2365     /* Determine if a packet is present. If so, derive the event from the packet.  */
2366     if (packet_ptr)
2367     {
2368 
2369 #ifndef NX_PPP_DISABLE_INFO
2370 
2371         /* Increment the number of LCP frames received.  */
2372         ppp_ptr -> nx_ppp_lcp_frames_received++;
2373 #endif
2374 
2375         /* Setup a pointer to the LCP pointer.  */
2376         lcp_message_ptr =  packet_ptr -> nx_packet_prepend_ptr;
2377 
2378         /* Pickup the type of received LCP code.  */
2379         code =  packet_ptr -> nx_packet_prepend_ptr[2];
2380 
2381 #ifndef NX_PPP_DISABLE_INFO
2382 
2383         /* Count the number of specific LCP requests.  */
2384         switch (code)
2385         {
2386 
2387         case NX_PPP_LCP_CONFIGURE_REQUEST:
2388 
2389             /* Increment the number of LCP configure requests received.  */
2390             ppp_ptr -> nx_ppp_lcp_configure_requests_received++;
2391             break;
2392 
2393         case NX_PPP_LCP_CONFIGURE_ACK:
2394 
2395             /* Increment the number of LCP configure ACKs received.  */
2396             ppp_ptr -> nx_ppp_lcp_configure_acks_received++;
2397             break;
2398 
2399         case NX_PPP_LCP_CONFIGURE_NAK:
2400 
2401             /* Increment the number of LCP configure NAKs received.  */
2402             ppp_ptr -> nx_ppp_lcp_configure_naks_received++;
2403             break;
2404 
2405         case NX_PPP_LCP_CONFIGURE_REJECT:
2406 
2407             /* Increment the number of LCP configure rejects received.  */
2408             ppp_ptr -> nx_ppp_lcp_configure_rejects_received++;
2409             break;
2410 
2411         case NX_PPP_LCP_TERMINATE_REQUEST:
2412 
2413             /* Increment the number of LCP terminate requests received.  */
2414             ppp_ptr -> nx_ppp_lcp_terminate_requests_received++;
2415             break;
2416 
2417         case NX_PPP_LCP_TERMINATE_ACK:
2418 
2419             /* Increment the number of LCP terminate ACKs received.  */
2420             ppp_ptr -> nx_ppp_lcp_terminate_acks_received++;
2421             break;
2422 
2423         case NX_PPP_LCP_CODE_REJECT:
2424 
2425             /* Increment the number of LCP code rejects received.  */
2426             ppp_ptr -> nx_ppp_lcp_code_rejects_received++;
2427             break;
2428 
2429         case NX_PPP_LCP_PROTOCOL_REJECT:
2430 
2431             /* Increment the number of LCP protocol rejects received.  */
2432             ppp_ptr -> nx_ppp_lcp_protocol_rejects_received++;
2433             break;
2434 
2435         case NX_PPP_LCP_ECHO_REQUEST:
2436 
2437             /* Increment the number of LCP echo requests received.  */
2438             ppp_ptr -> nx_ppp_lcp_echo_requests_received++;
2439 
2440             break;
2441 
2442         case NX_PPP_LCP_ECHO_REPLY:
2443 
2444                 /* Increment the number of LCP echo replies received.  */
2445                 break;
2446 
2447         case NX_PPP_LCP_DISCARD_REQUEST:
2448 
2449             /* Increment the number of LCP discard requests received.  */
2450             ppp_ptr -> nx_ppp_lcp_discard_requests_received++;
2451             break;
2452 
2453         default:
2454 
2455             /* Increment the number of LCP unknown (unhandled) requests received.  */
2456             ppp_ptr -> nx_ppp_lcp_unknown_requests_received++;
2457         }
2458 #endif
2459 
2460         /* Remember receive id.  */
2461         ppp_ptr -> nx_ppp_receive_id =  packet_ptr -> nx_packet_prepend_ptr[3];
2462 
2463         /* Is the code supported by PPP?  */
2464         if ((code < NX_PPP_LCP_CONFIGURE_REQUEST) ||
2465             (code > NX_PPP_LCP_DISCARD_REQUEST))
2466         {
2467 
2468             /* No, this code is not supported. Reject the code.  */
2469             _nx_ppp_lcp_code_reject(ppp_ptr, lcp_message_ptr);
2470 
2471             /* Return.  */
2472             return;
2473         }
2474     }
2475     else
2476     {
2477 
2478         /* Set the LCP pointer to NULL.  */
2479         lcp_message_ptr =  NX_NULL;
2480 
2481         /* Set the code to timeout to indicate a timeout has occurred.  */
2482         code =  NX_PPP_LCP_TIMEOUT;
2483 
2484 #ifndef NX_PPP_DISABLE_INFO
2485 
2486         /* Determine if we are in the initial state. If so, this really isn't a timeout.  */
2487         if (ppp_ptr -> nx_ppp_lcp_state != NX_PPP_LCP_START_STATE)
2488         {
2489 
2490             /* Increment the LCP timeout counter.  */
2491             ppp_ptr -> nx_ppp_lcp_state_machine_timeouts++;
2492         }
2493 #endif
2494     }
2495 
2496     /* Process relative to the current state.  */
2497     switch (ppp_ptr -> nx_ppp_lcp_state)
2498     {
2499 
2500         case NX_PPP_LCP_START_STATE:
2501         {
2502 
2503             /* Initial LCP state.  */
2504 
2505             /* Initialize the NAK and rejected lists.  */
2506 #ifndef NX_PPP_DNS_OPTION_DISABLE
2507 
2508             ppp_ptr -> nx_ppp_naked_list[0] =       0;
2509 #else
2510             ppp_ptr -> nx_ppp_naked_list[0] =       1;
2511 #endif
2512             ppp_ptr -> nx_ppp_peer_naked_list[0] =  0;
2513             ppp_ptr -> nx_ppp_rejected_list[0] =    0;
2514 
2515             /* Setup the retry counter.  */
2516             ppp_ptr -> nx_ppp_protocol_retry_counter =  0;
2517 
2518             /* Setup the timeout.  */
2519             ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
2520 
2521             /* Send configuration request to peer.  */
2522             _nx_ppp_lcp_configure_request_send(ppp_ptr);
2523 
2524             /* Move to the next state.  */
2525             ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_CONFIGURE_REQUEST_SENT_STATE;
2526             break;
2527         }
2528 
2529         case NX_PPP_LCP_CONFIGURE_REQUEST_SENT_STATE:
2530         {
2531 
2532             /* In this state, we have sent a configuration request but had not received an ACK
2533                or a configuration request from the peer.  */
2534 
2535             /* Process relative to the incoming code.  */
2536             if (code ==  NX_PPP_LCP_CONFIGURE_ACK)
2537             {
2538 
2539                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
2540                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
2541                 {
2542 
2543 #ifndef NX_PPP_DISABLE_INFO
2544 
2545                     /* Increment the invalid frame ID counter.  */
2546                     ppp_ptr -> nx_ppp_invalid_frame_id++;
2547 #endif
2548 
2549                     /* Discard this request by simply returning!  */
2550                     return;
2551                 }
2552 
2553                 /* The peer has ACKed our configuration request. Move to the
2554                    configure request ACKed state.  */
2555                 ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_CONFIGURE_REQUEST_ACKED_STATE;
2556 
2557                 /* Turn off the timeout for the configuration request.  */
2558                 ppp_ptr -> nx_ppp_timeout =  0;
2559             }
2560 
2561             else if (code ==  NX_PPP_LCP_CONFIGURE_NAK)
2562             {
2563 
2564                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
2565                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
2566                 {
2567 
2568 #ifndef NX_PPP_DISABLE_INFO
2569 
2570                     /* Increment the invalid frame ID counter.  */
2571                     ppp_ptr -> nx_ppp_invalid_frame_id++;
2572 #endif
2573 
2574                     /* Discard this request by simply returning!  */
2575                     return;
2576                 }
2577 
2578                 /* Figure out what options were naked.  */
2579                 _nx_ppp_lcp_nak_configure_list(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
2580 
2581                 /* Send new configure request.  */
2582                 _nx_ppp_lcp_configure_request_send(ppp_ptr);
2583             }
2584 
2585             else if ((code == NX_PPP_LCP_CONFIGURE_REQUEST) && (packet_ptr))
2586             {
2587 
2588                 /* The peer has sent a configuration request.  */
2589 
2590                 /* Retrieve configuration.  */
2591                 status = _nx_ppp_lcp_configuration_retrieve(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, &configure_status);
2592 
2593                 /* Discard invalid packet.  */
2594                 if (status)
2595                 {
2596                     return;
2597                 }
2598 
2599                 /* Determine if the configuration request is fine or needs to be negotiated further.  */
2600                 if (configure_status == 0)
2601                 {
2602 
2603                     /* The peer's request is acceptable, move into peer configuration request ACKed state.  */
2604                     ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_PEER_CONFIGURE_REQUEST_ACKED_STATE;
2605                 }
2606 
2607                 /* Send configuration reply.  */
2608                 _nx_ppp_lcp_configure_reply_send(ppp_ptr, configure_status, lcp_message_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list);
2609             }
2610             else if (code == NX_PPP_LCP_TIMEOUT)
2611             {
2612 
2613                 /* Increment the retry counter.  */
2614                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
2615 
2616                 /* Determine if the LCP retry counter has been exceeded.  */
2617                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_LCP_PROTOCOL_RETRIES)
2618                 {
2619 
2620                     /* Setup the timeout.  */
2621                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
2622 
2623                     /* Timeout, send configuration request again.  */
2624                     _nx_ppp_lcp_configure_request_send(ppp_ptr);
2625                 }
2626                 else
2627                 {
2628 
2629                     /* Retry counter exceeded.  */
2630 
2631                     /* Enter LCP failed state.  PPP must be stopped and started to try again.  */
2632                     ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_FAILED_STATE;
2633 
2634                     /* Determine if the application has registered a link down notification
2635                        callback.  */
2636                     if (ppp_ptr -> nx_ppp_link_down_callback)
2637                     {
2638 
2639                         /* Yes, call the application's callback function.  */
2640                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
2641                     }
2642                 }
2643             }
2644 #ifndef NX_PPP_DISABLE_INFO
2645             else
2646             {
2647 
2648                 /* Increment the number of unhandled state machine events.   */
2649                 ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
2650             }
2651 #endif
2652             break;
2653         }
2654 
2655         case NX_PPP_LCP_CONFIGURE_REQUEST_ACKED_STATE:
2656         {
2657 
2658             /* In this state, we have received the ACK for our configuration request, but have not yet
2659                received a configuration request from the peer.  */
2660 
2661             /* Process relative to the incoming code.  */
2662             if ((code == NX_PPP_LCP_CONFIGURE_REQUEST) && (packet_ptr))
2663             {
2664 
2665                 /* The peer has sent a configuration request.  */
2666 
2667                 /* Retrieve configuration.  */
2668                 status = _nx_ppp_lcp_configuration_retrieve(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, &configure_status);
2669 
2670                 /* Discard invalid packet.  */
2671                 if (status)
2672                 {
2673                     return;
2674                 }
2675 
2676                 /* Determine if the configuration request is fine or needs to be negotiated further.  */
2677                 if (configure_status == 0)
2678                 {
2679 
2680                     /* The peer's request is acceptable, move into the LCP done state.  */
2681                     ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_COMPLETED_STATE;
2682 
2683                     /* Determine if we need to update the IP's MTU.  */
2684                     if (ppp_ptr -> nx_ppp_mru > (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size)
2685                     {
2686 
2687                         /* Yes, the peer can accept larger messages than the default.  */
2688                         (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size =  ppp_ptr -> nx_ppp_mru;
2689                     }
2690 
2691                     /* Disable the LCP timeout.  */
2692                     ppp_ptr -> nx_ppp_timeout =  0;
2693                 }
2694 
2695                 /* Send configuration reply.  */
2696                 _nx_ppp_lcp_configure_reply_send(ppp_ptr, configure_status, lcp_message_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list);
2697             }
2698 #ifndef NX_PPP_DISABLE_INFO
2699             else
2700             {
2701 
2702                 /* Increment the number of unhandled state machine events.   */
2703                 ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
2704             }
2705 #endif
2706             break;
2707         }
2708 
2709         case NX_PPP_LCP_PEER_CONFIGURE_REQUEST_ACKED_STATE:
2710         {
2711 
2712             /* In this state, we have sent our configuration request, but haven't received an ACK. We have also received
2713                a peer configuration request and have ACKed that request.  */
2714 
2715             /* Process relative to the incoming code.  */
2716             if (code ==  NX_PPP_LCP_CONFIGURE_ACK)
2717             {
2718 
2719                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
2720                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
2721                 {
2722 
2723 #ifndef NX_PPP_DISABLE_INFO
2724 
2725                     /* Increment the invalid frame ID counter.  */
2726                     ppp_ptr -> nx_ppp_invalid_frame_id++;
2727 #endif
2728 
2729                     /* Discard this request by simply returning!  */
2730                     return;
2731                 }
2732 
2733                 /* The peer has ACKed our configuration request. Move to the
2734                    LCP completed state.  */
2735                 ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_COMPLETED_STATE;
2736 
2737                 /* Determine if we need to update the IP's MTU.  */
2738                 if (ppp_ptr -> nx_ppp_mru > (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size)
2739                 {
2740 
2741                     /* Yes, the peer can accept larger messages than the default.  */
2742                     (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size =  ppp_ptr -> nx_ppp_mru;
2743                 }
2744 
2745                 /* Turn off the timeout for the configuration request.  */
2746                 ppp_ptr -> nx_ppp_timeout =  0;
2747             }
2748 
2749             else if (code ==  NX_PPP_LCP_CONFIGURE_NAK)
2750             {
2751 
2752                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
2753                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
2754                 {
2755 
2756 #ifndef NX_PPP_DISABLE_INFO
2757 
2758                     /* Increment the invalid frame ID counter.  */
2759                     ppp_ptr -> nx_ppp_invalid_frame_id++;
2760 #endif
2761 
2762                     /* Discard this request by simply returning!  */
2763                     return;
2764                 }
2765 
2766                 /* Figure out what options were naked.  */
2767                 _nx_ppp_lcp_nak_configure_list(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
2768 
2769                 /* Send new configure request.  */
2770                 _nx_ppp_lcp_configure_request_send(ppp_ptr);
2771             }
2772 
2773             else if (code == NX_PPP_LCP_TIMEOUT)
2774             {
2775 
2776                 /* Increment the retry counter.  */
2777                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
2778 
2779                 /* Determine if the LCP retry counter has been exceeded.  */
2780                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_LCP_PROTOCOL_RETRIES)
2781                 {
2782 
2783                     /* Setup the timeout.  */
2784                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
2785 
2786                     /* Timeout, send configuration request again.  */
2787                     _nx_ppp_lcp_configure_request_send(ppp_ptr);
2788                 }
2789                 else
2790                 {
2791 
2792                     /* Retry counter exceeded.  */
2793 
2794                     /* Enter LCP failed state.  PPP must be stopped and started to try again.  */
2795                     ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_FAILED_STATE;
2796 
2797                     /* Determine if the application has registered a link down notification
2798                        callback.  */
2799                     if (ppp_ptr -> nx_ppp_link_down_callback)
2800                     {
2801 
2802                         /* Yes, call the application's callback function.  */
2803                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
2804                     }
2805                 }
2806             }
2807 #ifndef NX_PPP_DISABLE_INFO
2808             else
2809             {
2810 
2811                 /* Increment the number of unhandled state machine events.   */
2812                 ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
2813             }
2814 #endif
2815             break;
2816         }
2817 
2818         case NX_PPP_LCP_COMPLETED_STATE:
2819         {
2820 
2821             /* PPP is up and operational at this point.  */
2822 
2823             /* Process relative to incoming code.  */
2824             if (code == NX_PPP_LCP_TERMINATE_REQUEST)
2825             {
2826 
2827                 /* ACK the terminate request.  */
2828                 _nx_ppp_lcp_terminate_ack_send(ppp_ptr);
2829 
2830                 /* Move to stopped state.  */
2831                 ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_STOPPED_STATE;
2832 
2833                 /* Set the event to stop the PPP instance.  */
2834                 tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
2835 
2836                 /* Determine if the application has registered a link down notification
2837                    callback.  */
2838                 if (ppp_ptr -> nx_ppp_link_down_callback)
2839                 {
2840 
2841                     /* Yes, call the application's callback function.  */
2842                     (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
2843                 }
2844             }
2845             else if ((code == NX_PPP_LCP_ECHO_REQUEST) && (packet_ptr))
2846             {
2847 
2848                 /* Respond to the echo request. */
2849                 _nx_ppp_lcp_ping_reply(ppp_ptr, packet_ptr);
2850             }
2851 
2852             else if ((code == NX_PPP_LCP_ECHO_REPLY) && (packet_ptr))
2853             {
2854 
2855                 /* Check if the PPP instance is waiting on an echo reply. */
2856                 if (ppp_ptr -> nx_ppp_lcp_echo_reply_id)
2857                 {
2858 
2859                     /* It is. Check if this is a valid reply. */
2860                     _nx_ppp_lcp_ping_process_echo_reply(ppp_ptr, packet_ptr);
2861                 }
2862 
2863                 break;
2864             }
2865 
2866             /* In this state, we have received the ACK for our configuration request/completed LCP, but are expecting
2867                a configuration request from the peer.  */
2868 
2869             /* Process relative to the incoming code.  */
2870             else if ((code == NX_PPP_LCP_CONFIGURE_REQUEST) && (packet_ptr))
2871             {
2872 
2873                 /* The peer has sent a configuration request.  */
2874 
2875                 /* Retrieve configuration.  */
2876                 status = _nx_ppp_lcp_configuration_retrieve(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, &configure_status);
2877 
2878                 /* Discard invalid packet.  */
2879                 if (status)
2880                 {
2881                     return;
2882                 }
2883 
2884                 /* Determine if the configuration request is fine or needs to be negotiated further.  */
2885                 if (configure_status == 0)
2886                 {
2887 
2888 
2889                     /* The peer's request is acceptable, move into the LCP done state.  */
2890                     ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_COMPLETED_STATE;
2891 
2892                     /* Determine if we need to update the IP's MTU.  */
2893                     if (ppp_ptr -> nx_ppp_mru > (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size)
2894                     {
2895 
2896                         /* Yes, the peer can accept larger messages than the default.  */
2897                         (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_mtu_size =  ppp_ptr -> nx_ppp_mru;
2898                     }
2899                 }
2900 
2901                 /* Send configuration reply.  */
2902                 _nx_ppp_lcp_configure_reply_send(ppp_ptr, configure_status, lcp_message_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list);
2903             }
2904 #ifndef NX_PPP_DISABLE_INFO
2905             else
2906             {
2907 
2908                 /* Increment the number of unhandled state machine events. */
2909                 ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
2910             }
2911 #endif
2912             break;
2913         }
2914 
2915         case NX_PPP_LCP_STOPPING_STATE:
2916         {
2917 
2918             /* We received a terminate request from the other side and just need to get the ACK.  */
2919 
2920             /* Process relative to incoming code.  */
2921             if (code == NX_PPP_LCP_TERMINATE_ACK)
2922             {
2923 
2924                 /* Move to stopped state.  */
2925                 ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_STOPPED_STATE;
2926 
2927                 /* Set the event to stop the PPP instance.  */
2928                 tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
2929 
2930                 /* Determine if the application has registered a link down notification
2931                     callback.  */
2932                 if (ppp_ptr -> nx_ppp_link_down_callback)
2933                 {
2934 
2935                     /* Yes, call the application's callback function.  */
2936                     (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
2937                 }
2938             }
2939             else if (code == NX_PPP_LCP_TIMEOUT)
2940             {
2941 
2942                 /* Increment the retry counter.  */
2943                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
2944 
2945                 /* Determine if the LCP retry counter has been exceeded.  */
2946                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_LCP_PROTOCOL_RETRIES)
2947                 {
2948 
2949                     /* Setup the timeout.  */
2950                    ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
2951 
2952                     /* Send terminate request.  */
2953                     _nx_ppp_lcp_terminate_request_send(ppp_ptr);
2954                 }
2955                 else
2956                 {
2957 
2958                     /* Retry counter exceeded.  */
2959 
2960                     /* Enter LCP failed state.  */
2961                     ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_FAILED_STATE;
2962 
2963                     /* Set the event to stop the PPP instance.  */
2964                     tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
2965 
2966                     /* Determine if the application has registered a link down notification
2967                        callback.  */
2968                     if (ppp_ptr -> nx_ppp_link_down_callback)
2969                     {
2970 
2971                         /* Yes, call the application's callback function.  */
2972                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
2973                     }
2974                 }
2975             }
2976 #ifndef NX_PPP_DISABLE_INFO
2977             else
2978             {
2979 
2980 #ifndef NX_PPP_DISABLE_INFO
2981                 if (code == NX_PPP_LCP_ECHO_REQUEST)
2982                 {
2983 
2984 
2985                     ppp_ptr -> nx_ppp_lcp_echo_requests_dropped++;
2986                 }
2987 #endif
2988 
2989                 /* Increment the number of unhandled state machine events.   */
2990                 ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
2991             }
2992 #endif
2993             break;
2994         }
2995 
2996         default:
2997         {
2998 
2999 #ifndef NX_PPP_DISABLE_INFO
3000             {
3001 
3002                 /* Increment the number of unhandled state machine events.   */
3003                 ppp_ptr -> nx_ppp_lcp_state_machine_unhandled_requests++;
3004             }
3005 #endif
3006             break;
3007         }
3008     }
3009 }
3010 
3011 
3012 /**************************************************************************/
3013 /*                                                                        */
3014 /*  FUNCTION                                               RELEASE        */
3015 /*                                                                        */
3016 /*    _nx_ppp_lcp_code_reject                             PORTABLE C      */
3017 /*                                                           6.1          */
3018 /*  AUTHOR                                                                */
3019 /*                                                                        */
3020 /*    Yuxin Zhou, Microsoft Corporation                                   */
3021 /*                                                                        */
3022 /*  DESCRIPTION                                                           */
3023 /*                                                                        */
3024 /*    This function builds a code reject message and sends it out.        */
3025 /*                                                                        */
3026 /*  INPUT                                                                 */
3027 /*                                                                        */
3028 /*    ppp_ptr                               PPP instance pointer          */
3029 /*    lcp_ptr                               Pointer to LCP message        */
3030 /*                                                                        */
3031 /*  OUTPUT                                                                */
3032 /*                                                                        */
3033 /*    None                                                                */
3034 /*                                                                        */
3035 /*  CALLS                                                                 */
3036 /*                                                                        */
3037 /*    nx_packet_allocate                    Allocate a packet for sending */
3038 /*    _nx_ppp_packet_transmit               Send PPP packet               */
3039 /*                                                                        */
3040 /*  CALLED BY                                                             */
3041 /*                                                                        */
3042 /*    _nx_ppp_lcp_state_machine_update      LCP state machine processing  */
3043 /*                                                                        */
3044 /*  RELEASE HISTORY                                                       */
3045 /*                                                                        */
3046 /*    DATE              NAME                      DESCRIPTION             */
3047 /*                                                                        */
3048 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3049 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3050 /*                                            resulting in version 6.1    */
3051 /*                                                                        */
3052 /**************************************************************************/
_nx_ppp_lcp_code_reject(NX_PPP * ppp_ptr,UCHAR * lcp_ptr)3053 void  _nx_ppp_lcp_code_reject(NX_PPP *ppp_ptr, UCHAR *lcp_ptr)
3054 {
3055 
3056 UINT        i;
3057 UINT        status;
3058 UINT        length;
3059 NX_PACKET   *packet_ptr;
3060 
3061 
3062     /* Allocate a packet for the PPP packet.  */
3063     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
3064 
3065     /* Determine if the packet was allocated successfully.  */
3066     if (status != NX_SUCCESS)
3067     {
3068 
3069 #ifndef NX_PPP_DISABLE_INFO
3070 
3071         /* Increment the number of packet allocation timeouts.  */
3072         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
3073 #endif
3074 
3075         /* An error was detected, simply return.  */
3076         return;
3077     }
3078 
3079     /* Build the configuration request.  */
3080     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
3081     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_LCP_PROTOCOL & 0xFF;
3082     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_LCP_CODE_REJECT;
3083     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_receive_id;
3084 
3085     /* Setup the length.  */
3086     packet_ptr -> nx_packet_prepend_ptr[4] =  lcp_ptr[4];
3087     packet_ptr -> nx_packet_prepend_ptr[5] =  lcp_ptr[5];
3088 
3089     length =  (((UINT) lcp_ptr[4]) << 8) | ((UINT) lcp_ptr[5]);
3090 
3091     /* Check if out of boundary.  */
3092     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (length + 2))
3093      {
3094 
3095         /* Release the packet.  */
3096         nx_packet_release(packet_ptr);
3097         return;
3098     }
3099 
3100     /* Send the options that were received with RCR.  */
3101     for(i = 0; i < (length - 4); i++)
3102     {
3103 
3104         /* Copy option byte into new packet.  */
3105         packet_ptr -> nx_packet_prepend_ptr[6+i] =  lcp_ptr[6+i];
3106     }
3107 
3108     /* Setup the packet length and append pointer.  */
3109     packet_ptr -> nx_packet_length =  length + 2;
3110     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3111 
3112 #ifndef NX_PPP_DISABLE_INFO
3113 
3114     /* Increment the number of LCP frames sent.  */
3115     ppp_ptr -> nx_ppp_lcp_frames_sent++;
3116 
3117     /* Increment code rejects sent counter.  */
3118     ppp_ptr -> nx_ppp_lcp_code_rejects_sent++;
3119 #endif
3120 
3121     /* Send code reject message.  */
3122     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
3123 }
3124 
3125 
3126 /**************************************************************************/
3127 /*                                                                        */
3128 /*  FUNCTION                                               RELEASE        */
3129 /*                                                                        */
3130 /*    _nx_ppp_lcp_configure_reply_send                    PORTABLE C      */
3131 /*                                                           6.1          */
3132 /*  AUTHOR                                                                */
3133 /*                                                                        */
3134 /*    Yuxin Zhou, Microsoft Corporation                                   */
3135 /*                                                                        */
3136 /*  DESCRIPTION                                                           */
3137 /*                                                                        */
3138 /*    This function builds and sends a configuration reply.               */
3139 /*                                                                        */
3140 /*  INPUT                                                                 */
3141 /*                                                                        */
3142 /*    ppp_ptr                               PPP instance pointer          */
3143 /*    configure_status                      Status from configure request */
3144 /*    lcp_ptr                               Pointer to LCP message        */
3145 /*    naked_list                            List of NAKed options         */
3146 /*    rejected_list                         List of rejected options      */
3147 /*                                                                        */
3148 /*  OUTPUT                                                                */
3149 /*                                                                        */
3150 /*    None                                                                */
3151 /*                                                                        */
3152 /*  CALLS                                                                 */
3153 /*                                                                        */
3154 /*    nx_packet_allocate                    Allocate a packet for sending */
3155 /*    _nx_ppp_packet_transmit               Send PPP packet               */
3156 /*                                                                        */
3157 /*  CALLED BY                                                             */
3158 /*                                                                        */
3159 /*    _nx_ppp_lcp_state_machine_update      LCP state machine processing  */
3160 /*                                                                        */
3161 /*  RELEASE HISTORY                                                       */
3162 /*                                                                        */
3163 /*    DATE              NAME                      DESCRIPTION             */
3164 /*                                                                        */
3165 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3166 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3167 /*                                            resulting in version 6.1    */
3168 /*                                                                        */
3169 /**************************************************************************/
_nx_ppp_lcp_configure_reply_send(NX_PPP * ppp_ptr,UINT configure_status,UCHAR * lcp_ptr,UCHAR * naked_list,UCHAR * rejected_list)3170 void  _nx_ppp_lcp_configure_reply_send(NX_PPP *ppp_ptr, UINT configure_status, UCHAR *lcp_ptr, UCHAR *naked_list, UCHAR *rejected_list)
3171 {
3172 
3173 UINT        i;
3174 UINT        status;
3175 UINT        length;
3176 NX_PACKET   *packet_ptr;
3177 
3178 
3179     /* Allocate a packet for the PPP packet.  */
3180     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
3181 
3182     /* Determine if the packet was allocated successfully.  */
3183     if (status != NX_SUCCESS)
3184     {
3185 
3186 #ifndef NX_PPP_DISABLE_INFO
3187 
3188         /* Increment the number of packet allocation timeouts.  */
3189         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
3190 #endif
3191 
3192         /* An error was detected, simply return a NULL pointer.  */
3193         return;
3194     }
3195 
3196     /* Build the configuration reply.  */
3197     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
3198     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_LCP_PROTOCOL & 0xFF;
3199 
3200     /* Process relative to the supplied status.  */
3201     if (configure_status == 0)
3202     {
3203         /* Send ACK.  */
3204         packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_LCP_CONFIGURE_ACK;
3205 
3206 #ifndef NX_PPP_DISABLE_INFO
3207 
3208         /* Increment the number of LCP ACKs sent.  */
3209         ppp_ptr -> nx_ppp_lcp_configure_acks_sent++;
3210 #endif
3211     }
3212     else if (configure_status & 2)
3213     {
3214         /* Send reject.  */
3215         packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_LCP_CONFIGURE_REJECT;
3216 
3217 #ifndef NX_PPP_DISABLE_INFO
3218 
3219         /* Increment the number of LCP rejects sent.  */
3220         ppp_ptr -> nx_ppp_lcp_configure_rejects_sent++;
3221 #endif
3222     }
3223     else
3224     {
3225         /* Send NAK.  */
3226         packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_LCP_CONFIGURE_NAK;
3227 
3228 #ifndef NX_PPP_DISABLE_INFO
3229 
3230         /* Increment the number of LCP NAKs sent.  */
3231         ppp_ptr -> nx_ppp_lcp_configure_naks_sent++;
3232 #endif
3233     }
3234 
3235     /* Insert the id.  */
3236     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_receive_id;
3237 
3238     /* Process again according to the status.  */
3239     if (configure_status == 0)
3240     {
3241 
3242         /* Setup the options list.  */
3243 
3244         /* Setup the length.  */
3245         packet_ptr -> nx_packet_prepend_ptr[4] =  lcp_ptr[4];
3246         packet_ptr -> nx_packet_prepend_ptr[5] =  lcp_ptr[5];
3247 
3248         length =  (((UINT) lcp_ptr[4]) << 8) | ((UINT) lcp_ptr[5]);
3249 
3250         /* Check if out of boundary.  */
3251         if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (length + 2))
3252          {
3253 
3254             /* Release the packet.  */
3255             nx_packet_release(packet_ptr);
3256             return;
3257         }
3258 
3259         /* Send the options that were received with the request.  */
3260         for(i = 0; i < (length - 4); i++)
3261         {
3262 
3263             /* Copy option byte into new packet.  */
3264             packet_ptr -> nx_packet_prepend_ptr[6+i] =  lcp_ptr[6+i];
3265         }
3266 
3267         /* Setup the packet length and append pointer.  */
3268         packet_ptr -> nx_packet_length =  length + 2;
3269         packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3270     }
3271     else if (configure_status & 2)
3272     {
3273 
3274         /* Rejected options.  */
3275 
3276         /* Setup the length.  */
3277         packet_ptr -> nx_packet_prepend_ptr[4] =  0;
3278         packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR)(rejected_list[0] + 4);
3279 
3280         /* Check if out of boundary.  */
3281         if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(rejected_list[0] + 6))
3282          {
3283 
3284             /* Release the packet.  */
3285             nx_packet_release(packet_ptr);
3286             return;
3287         }
3288 
3289         /* Load entire rejected list.  */
3290         for(i = 1; i < (UCHAR)(rejected_list[0] + 1); i++)
3291         {
3292             /* Copy option byte into new packet.  */
3293             packet_ptr -> nx_packet_prepend_ptr[6+i-1] =  rejected_list[i];
3294         }
3295 
3296         /* Setup the packet length and append pointer.  */
3297         packet_ptr -> nx_packet_length =  (ULONG)(rejected_list[0] + 6);
3298         packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3299     }
3300     else
3301     {
3302 
3303         /* NAKed options.  */
3304 
3305         /* Setup the length.  */
3306         packet_ptr -> nx_packet_prepend_ptr[4] =  0;
3307         packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR)(naked_list[0] + 4);
3308 
3309         /* Check if out of boundary.  */
3310         if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(naked_list[0] + 6))
3311          {
3312 
3313             /* Release the packet.  */
3314             nx_packet_release(packet_ptr);
3315             return;
3316         }
3317 
3318         /* Load entire naked list.  */
3319         for(i = 1; i < (UCHAR)(naked_list[0] + 1); i++)
3320         {
3321             /* Copy option byte into new packet.  */
3322             packet_ptr -> nx_packet_prepend_ptr[6+i-1] =  naked_list[i];
3323         }
3324 
3325         /* Setup the packet length and append pointer.  */
3326         packet_ptr -> nx_packet_length =  (ULONG)(naked_list[0] + 6);
3327         packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3328     }
3329 
3330 #ifndef NX_PPP_DISABLE_INFO
3331 
3332     /* Increment the number of LCP frames sent.  */
3333     ppp_ptr -> nx_ppp_lcp_frames_sent++;
3334 #endif
3335 
3336     /* Send the reply out.  */
3337     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
3338 }
3339 
3340 
3341 /**************************************************************************/
3342 /*                                                                        */
3343 /*  FUNCTION                                               RELEASE        */
3344 /*                                                                        */
3345 /*    _nx_ppp_lcp_configure_request_send                  PORTABLE C      */
3346 /*                                                           6.3.0        */
3347 /*  AUTHOR                                                                */
3348 /*                                                                        */
3349 /*    Yuxin Zhou, Microsoft Corporation                                   */
3350 /*                                                                        */
3351 /*  DESCRIPTION                                                           */
3352 /*                                                                        */
3353 /*    This function builds and sends a LCP configuration request.         */
3354 /*                                                                        */
3355 /*  INPUT                                                                 */
3356 /*                                                                        */
3357 /*    ppp_ptr                               PPP instance pointer          */
3358 /*                                                                        */
3359 /*  OUTPUT                                                                */
3360 /*                                                                        */
3361 /*    None                                                                */
3362 /*                                                                        */
3363 /*  CALLS                                                                 */
3364 /*                                                                        */
3365 /*    nx_packet_allocate                    Allocate PPP packet           */
3366 /*    _nx_ppp_packet_transmit               Send LCP packet               */
3367 /*                                                                        */
3368 /*  CALLED BY                                                             */
3369 /*                                                                        */
3370 /*    _nx_ppp_lcp_state_machine_update      LCP state machine processing  */
3371 /*                                                                        */
3372 /*  RELEASE HISTORY                                                       */
3373 /*                                                                        */
3374 /*    DATE              NAME                      DESCRIPTION             */
3375 /*                                                                        */
3376 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3377 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3378 /*                                            resulting in version 6.1    */
3379 /*  10-31-2023     Wenhui Xie               Modified comment(s), and      */
3380 /*                                            supported processing        */
3381 /*                                            compressed data,            */
3382 /*                                            resulting in version 6.3.0  */
3383 /*                                                                        */
3384 /**************************************************************************/
_nx_ppp_lcp_configure_request_send(NX_PPP * ppp_ptr)3385 void  _nx_ppp_lcp_configure_request_send(NX_PPP *ppp_ptr)
3386 {
3387 UINT        status;
3388 NX_PACKET   *packet_ptr;
3389 UINT        index = 0;
3390 UINT        length_index = 0;
3391 
3392 
3393     /* Allocate a packet for the PPP packet.  */
3394     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
3395 
3396     /* Determine if the packet was allocated successfully.  */
3397     if (status != NX_SUCCESS)
3398     {
3399 
3400 #ifndef NX_PPP_DISABLE_INFO
3401 
3402         /* Increment the number of packet allocation timeouts.  */
3403         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
3404 #endif
3405 
3406         /* An error was detected, simply return a NULL pointer.  */
3407         return;
3408     }
3409 
3410     /* Increment the transmit ID.  */
3411     ppp_ptr -> nx_ppp_transmit_id++;
3412 
3413     /* Build the configuration request.  */
3414     packet_ptr -> nx_packet_prepend_ptr[index++] =  (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
3415     packet_ptr -> nx_packet_prepend_ptr[index++] =  NX_PPP_LCP_PROTOCOL & 0xFF;
3416     packet_ptr -> nx_packet_prepend_ptr[index++] =  NX_PPP_LCP_CONFIGURE_REQUEST;
3417     packet_ptr -> nx_packet_prepend_ptr[index++] =  ppp_ptr -> nx_ppp_transmit_id;
3418 
3419     /* Store the index of length field and skip the length field.  */
3420     length_index = index;
3421     index += 2;
3422 
3423     /* Load the MRU.  */
3424     packet_ptr -> nx_packet_prepend_ptr[index++] =  1;
3425     packet_ptr -> nx_packet_prepend_ptr[index++] =  4;
3426     packet_ptr -> nx_packet_prepend_ptr[index++] =  (UCHAR) ((NX_PPP_MRU) >> 8);
3427     packet_ptr -> nx_packet_prepend_ptr[index++] =  (UCHAR) ((NX_PPP_MRU) & 0xff);
3428 
3429     /* Load the authentication protocol type. */
3430     if ((ppp_ptr -> nx_ppp_verify_authentication_protocol == NX_PPP_PAP_PROTOCOL) && (ppp_ptr -> nx_ppp_pap_verify_login))
3431     {
3432 
3433         /* Set the PAP authentication protocol.  */
3434         packet_ptr -> nx_packet_prepend_ptr[index++] =  3;
3435         packet_ptr -> nx_packet_prepend_ptr[index++] =  4;
3436         packet_ptr -> nx_packet_prepend_ptr[index++] =  (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
3437         packet_ptr -> nx_packet_prepend_ptr[index++] =  NX_PPP_PAP_PROTOCOL & 0xFF;
3438     }
3439     else if ((ppp_ptr -> nx_ppp_verify_authentication_protocol == NX_PPP_CHAP_PROTOCOL) &&
3440              (ppp_ptr -> nx_ppp_chap_get_challenge_values) && (ppp_ptr -> nx_ppp_chap_get_verification_values))
3441     {
3442 
3443         /* Set the CHAP authentication protocol.  */
3444         packet_ptr -> nx_packet_prepend_ptr[index++] =  3;
3445         packet_ptr -> nx_packet_prepend_ptr[index++] =  5;
3446         packet_ptr -> nx_packet_prepend_ptr[index++] =  (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
3447         packet_ptr -> nx_packet_prepend_ptr[index++] =   NX_PPP_CHAP_PROTOCOL & 0xFF;
3448         packet_ptr -> nx_packet_prepend_ptr[index++] =  0x05;
3449     }
3450 
3451 #ifdef NX_PPP_COMPRESSION_ENABLE
3452 
3453     /* Add PFC and ACFC options.  */
3454     packet_ptr -> nx_packet_prepend_ptr[index++] = 7;
3455     packet_ptr -> nx_packet_prepend_ptr[index++] = 2;
3456     packet_ptr -> nx_packet_prepend_ptr[index++] = 8;
3457     packet_ptr -> nx_packet_prepend_ptr[index++] = 2;
3458 #endif /* NX_PPP_COMPRESSION_ENABLE */
3459 
3460     /* Update the length field.  */
3461     packet_ptr -> nx_packet_prepend_ptr[length_index] = (UCHAR)((index - 2) >> 8);
3462     packet_ptr -> nx_packet_prepend_ptr[length_index + 1] = (UCHAR)((index - 2) & 0xff);
3463 
3464     /* Setup the append pointer and the packet length (LCP length + PPP header).  */
3465     packet_ptr -> nx_packet_length =  (ULONG)(index);
3466     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3467 
3468 #ifndef NX_PPP_DISABLE_INFO
3469 
3470     /* Increment the number of LCP frames sent.  */
3471     ppp_ptr -> nx_ppp_lcp_frames_sent++;
3472 
3473     /* Increment the number of LCP configure requests sent.  */
3474     ppp_ptr -> nx_ppp_lcp_configure_requests_sent++;
3475 #endif
3476 
3477     /* Send the configure request packet.  */
3478     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
3479 }
3480 
3481 
3482 /**************************************************************************/
3483 /*                                                                        */
3484 /*  FUNCTION                                               RELEASE        */
3485 /*                                                                        */
3486 /*    _nx_ppp_lcp_configuration_retrieve                  PORTABLE C      */
3487 /*                                                           6.1.2        */
3488 /*  AUTHOR                                                                */
3489 /*                                                                        */
3490 /*    Yuxin Zhou, Microsoft Corporation                                   */
3491 /*                                                                        */
3492 /*  DESCRIPTION                                                           */
3493 /*                                                                        */
3494 /*    This function pickup the configuration options. Unhandled options   */
3495 /*    are placed in NAKed or Rejected lists.                              */
3496 /*                                                                        */
3497 /*  INPUT                                                                 */
3498 /*                                                                        */
3499 /*    ppp_ptr                               PPP instance pointer          */
3500 /*    naked_list                            List of NAKed options         */
3501 /*    rejected_list                         List of rejected options      */
3502 /*    configure_status                      Returned configration status: */
3503 /*                                            0 -> Success                */
3504 /*                                            1 -> NAKed options          */
3505 /*                                            2 -> Rejected options       */
3506 /*                                                                        */
3507 /*  OUTPUT                                                                */
3508 /*                                                                        */
3509 /*    status                                Completion status             */
3510 /*                                                                        */
3511 /*  CALLS                                                                 */
3512 /*                                                                        */
3513 /*    None                                                                */
3514 /*                                                                        */
3515 /*  CALLED BY                                                             */
3516 /*                                                                        */
3517 /*    _nx_ppp_lcp_state_machine_update      LCP state machine processing  */
3518 /*                                                                        */
3519 /*  RELEASE HISTORY                                                       */
3520 /*                                                                        */
3521 /*    DATE              NAME                      DESCRIPTION             */
3522 /*                                                                        */
3523 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3524 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3525 /*                                            resulting in version 6.1    */
3526 /*  11-09-2020     Yuxin Zhou               Modified comment(s),          */
3527 /*                                            improved packet length      */
3528 /*                                            verification,               */
3529 /*                                            resulting in version 6.1.2  */
3530 /*                                                                        */
3531 /**************************************************************************/
_nx_ppp_lcp_configuration_retrieve(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr,UCHAR * naked_list,UCHAR * rejected_list,UINT * configure_status)3532 UINT  _nx_ppp_lcp_configuration_retrieve(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr, UCHAR *naked_list, UCHAR *rejected_list, UINT *configure_status)
3533 {
3534 
3535 UINT    option_index, nak_list_index, rejected_list_index;
3536 UINT    len;
3537 UINT    type;
3538 UINT    counter;
3539 ULONG   authentication_protocol;
3540 UCHAR   *option_data;
3541 
3542 
3543     /* Initialize the configure status.  */
3544     *configure_status = 0;
3545 
3546     /* Clear both the NAKed and rejected list length.   */
3547     naked_list[0] =     0;
3548     rejected_list[0] =  0;
3549 
3550     /* Start indexes at 1, since byte 0 contains length.  */
3551     nak_list_index =       1;
3552     rejected_list_index =  1;
3553 
3554     /* Process the options in the LCP message.  */
3555     for (option_index = 6; (option_index + 2) <= packet_ptr -> nx_packet_length; )
3556     {
3557 
3558         /* Pickup the option type - section 6 of RFC1661.  */
3559         type = packet_ptr -> nx_packet_prepend_ptr[option_index++];
3560 
3561         /* Get the length of the option. The length also includes the type and length fields.  */
3562         len =  packet_ptr -> nx_packet_prepend_ptr[option_index++];
3563 
3564         /* Check if the length is valid.  */
3565         if ((len < 2) || (len > (packet_ptr -> nx_packet_length - (option_index - 2))))
3566         {
3567             return(NX_PPP_BAD_PACKET);
3568         }
3569 
3570         /* Set a pointer to option data.  */
3571         option_data = &packet_ptr -> nx_packet_prepend_ptr[option_index];
3572 
3573         /* Advance the index to next option.  */
3574         option_index +=  len - 2;
3575 
3576         /* Process relative to the option type.  */
3577         switch (type)
3578         {
3579 
3580         case 1:
3581 
3582             /* Maximum Receive Unit (MRU) option.  */
3583             ppp_ptr -> nx_ppp_mru =  (ULONG)((((USHORT) option_data[0]) << 8) | ((USHORT) option_data[1]));
3584 
3585             /* Determine if the MRU is too small.  */
3586             if (ppp_ptr -> nx_ppp_mru < NX_PPP_MINIMUM_MRU)
3587             {
3588                 *configure_status |=  1;
3589 
3590                 /* Default the MRU.  */
3591                 ppp_ptr -> nx_ppp_mru =  NX_PPP_MRU;
3592 
3593                 /* Check if out of boundary.  */
3594                 if ((nak_list_index + len) > NX_PPP_OPTION_MESSAGE_LENGTH)
3595                     break;
3596 
3597                 /* Yes, enter it in the NAK list.  */
3598                 naked_list[nak_list_index++] =  (UCHAR)type;
3599                 naked_list[nak_list_index++] =  (UCHAR)len;
3600                 for (counter = 0; counter < (len-2); counter++)
3601                     naked_list[nak_list_index++] = option_data[counter];
3602                 naked_list[0] = (UCHAR)(nak_list_index - 1);
3603             }
3604             break;
3605 
3606         case 3:
3607 
3608             /* Authentication protocol selection.  */
3609 
3610             /* Pickup the authentication protocol.  */
3611             authentication_protocol =  (((UINT) option_data[0]) << 8) | ((UINT) option_data[1]);
3612 
3613             /* Determine if the authentication protocol specified by the peer is PAP and we have a generate
3614                routine defined.  */
3615             if ((authentication_protocol == NX_PPP_PAP_PROTOCOL) && (ppp_ptr -> nx_ppp_pap_generate_login))
3616             {
3617 
3618                 /* Yes, enable the PAP protocol.  */
3619                 ppp_ptr -> nx_ppp_generate_authentication_protocol =  NX_PPP_PAP_PROTOCOL;
3620             }
3621 
3622             /* Determine if the authentication protocol specified by the peer is CHAP and we have a generate
3623                response routine defined.  */
3624             if ((authentication_protocol == NX_PPP_CHAP_PROTOCOL) && (ppp_ptr -> nx_ppp_chap_get_responder_values))
3625             {
3626 
3627                 /* Yes, enable the CHAP protocol.  */
3628                 ppp_ptr -> nx_ppp_generate_authentication_protocol =  NX_PPP_CHAP_PROTOCOL;
3629             }
3630 
3631             /* Determine if the required authentication at the peer is the same as what this peer can generate
3632                login information for.  */
3633             if (ppp_ptr -> nx_ppp_generate_authentication_protocol != authentication_protocol)
3634             {
3635 
3636                 /* We do not support the requested authentication by the peer.  */
3637 
3638                 /* Check to see if we don't have any authentication protocols enabled.  */
3639                 if (ppp_ptr -> nx_ppp_generate_authentication_protocol == 0)
3640                 {
3641                     *configure_status |=  2;
3642 
3643                     /* Check if out of boundary.  */
3644                     if ((rejected_list_index + len) > NX_PPP_OPTION_MESSAGE_LENGTH)
3645                         break;
3646 
3647                     /* No authentication is supported, simply include requested authentication
3648                        option in the rejected list.  */
3649                     rejected_list[rejected_list_index++] =  (UCHAR)type;
3650                     rejected_list[rejected_list_index++] =  (UCHAR)len;
3651                     for (counter = 0; counter < (len-2); counter++)
3652                         rejected_list[rejected_list_index++] = option_data[counter];
3653                     rejected_list[0] = (UCHAR)(rejected_list_index - 1);
3654                 }
3655 
3656                 /* Determine if this peer has PAP enabled.  */
3657                 if (ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_PAP_PROTOCOL)
3658                 {
3659                     *configure_status |=  1;
3660 
3661                     /* Check if out of boundary.  */
3662                     if ((nak_list_index + 4) > NX_PPP_OPTION_MESSAGE_LENGTH)
3663                         break;
3664 
3665                     /* PAP enabled but something different is requested by the peer, build NAK entry with PAP hint.  */
3666                     naked_list[nak_list_index++] =  3;
3667                     naked_list[nak_list_index++] =  NX_PPP_PAP_AUTHENTICATE_NAK;
3668                     naked_list[nak_list_index++] =  (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
3669                     naked_list[nak_list_index++] =  NX_PPP_PAP_PROTOCOL & 0xFF;
3670                     naked_list[0] = (UCHAR)(nak_list_index - 1);
3671 
3672                     /* Clear authentication protocol.  */
3673                     ppp_ptr -> nx_ppp_verify_authentication_protocol =  0;
3674                 }
3675 
3676                 /* Determine if this peer has CHAP enabled.  */
3677                 if (ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_CHAP_PROTOCOL)
3678                 {
3679                     *configure_status |=  1;
3680 
3681                     /* Check if out of boundary.  */
3682                     if ((nak_list_index + 5) > NX_PPP_OPTION_MESSAGE_LENGTH)
3683                         break;
3684 
3685                     /* CHAP enabled but something different is requested by the peer, build NAK entry with CHAP hint.  */
3686                     naked_list[nak_list_index++] =  3;
3687                     naked_list[nak_list_index++] =  5;
3688                     naked_list[nak_list_index++] =  (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
3689                     naked_list[nak_list_index++] =  NX_PPP_CHAP_PROTOCOL & 0xFF;
3690                     naked_list[nak_list_index++] =  0x05;
3691                     naked_list[0] = (UCHAR)(nak_list_index - 1);
3692                 }
3693             }
3694             else
3695             {
3696 
3697                 /* Matching authentication protocol.  */
3698 
3699                 /* Check to see if we have the CHAP authentication protocol enabled.  */
3700                 if (ppp_ptr -> nx_ppp_generate_authentication_protocol == NX_PPP_CHAP_PROTOCOL)
3701                 {
3702 
3703                     /* Now determine if something other than CHAP MD5 was requested.  */
3704                     if (option_data[2] != 0x05)
3705                     {
3706                         *configure_status |=  1;
3707 
3708                         /* Check if out of boundary.  */
3709                         if ((nak_list_index + 5) > NX_PPP_OPTION_MESSAGE_LENGTH)
3710                             break;
3711 
3712                         /* CHAP enabled but something different is requested by the peer, build NAK entry with CHAP hint.  */
3713                         naked_list[nak_list_index++] =  3;
3714                         naked_list[nak_list_index++] =  5;
3715                         naked_list[nak_list_index++] =  (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
3716                         naked_list[nak_list_index++] =  NX_PPP_CHAP_PROTOCOL & 0xFF;
3717                         naked_list[nak_list_index++] =  0x05;
3718                         naked_list[0] = (UCHAR)(nak_list_index - 1);
3719                     }
3720                     else
3721                     {
3722 
3723                         /* Clear the authenticated flag since peer requires CHAP authentication.  */
3724                         ppp_ptr -> nx_ppp_authenticated =  NX_FALSE;
3725                     }
3726                 }
3727                 else
3728                 {
3729 
3730                     /* Clear the authenticated flag since peer requires PAP authentication.  */
3731                     ppp_ptr -> nx_ppp_authenticated =  NX_FALSE;
3732                 }
3733             }
3734             break;
3735 
3736         case 2: /* ACCM, Not implemented.  */
3737         case 5: /* Magic number - just acknowledge, we do not send out magic number.  */
3738         case 7: /* The sender can receive protocol compression.  */
3739         case 8: /* The sender can receive address compression.  */
3740 
3741             /* Skip these options, since we don't care to object.  */
3742             break;
3743 
3744         default:
3745 
3746             *configure_status |=  2;
3747 
3748             /* Check if out of boundary.  */
3749             if ((rejected_list_index + len) > NX_PPP_OPTION_MESSAGE_LENGTH)
3750                 break;
3751 
3752             /* All other options we must reject since we do not negotiate.  */
3753             rejected_list[rejected_list_index++] =  (UCHAR)type;
3754             rejected_list[rejected_list_index++] =  (UCHAR)len;
3755             for (counter = 0; counter < (len-2); counter++)
3756                 rejected_list[rejected_list_index++] = option_data[counter];
3757             rejected_list[0] = (UCHAR)(rejected_list_index - 1);
3758             break;
3759         }
3760     }
3761 
3762     /* Check if packet length is valid.  */
3763     if (option_index != packet_ptr -> nx_packet_length)
3764     {
3765         return(NX_PPP_BAD_PACKET);
3766     }
3767 
3768     /* Return status.  */
3769     return(NX_SUCCESS);
3770 }
3771 
3772 
3773 /**************************************************************************/
3774 /*                                                                        */
3775 /*  FUNCTION                                               RELEASE        */
3776 /*                                                                        */
3777 /*    _nx_ppp_lcp_nak_configure_list                      PORTABLE C      */
3778 /*                                                           6.1          */
3779 /*  AUTHOR                                                                */
3780 /*                                                                        */
3781 /*    Yuxin Zhou, Microsoft Corporation                                   */
3782 /*                                                                        */
3783 /*  DESCRIPTION                                                           */
3784 /*                                                                        */
3785 /*    This function processes the NAKed option list.                      */
3786 /*                                                                        */
3787 /*  INPUT                                                                 */
3788 /*                                                                        */
3789 /*    ppp_ptr                               PPP instance pointer          */
3790 /*    naked_list                            List of NAKed options         */
3791 /*                                                                        */
3792 /*  OUTPUT                                                                */
3793 /*                                                                        */
3794 /*    None                                                                */
3795 /*                                                                        */
3796 /*  CALLS                                                                 */
3797 /*                                                                        */
3798 /*    None                                                                */
3799 /*                                                                        */
3800 /*  CALLED BY                                                             */
3801 /*                                                                        */
3802 /*    _nx_ppp_lcp_state_machine_update      LCP state machine processing  */
3803 /*                                                                        */
3804 /*  RELEASE HISTORY                                                       */
3805 /*                                                                        */
3806 /*    DATE              NAME                      DESCRIPTION             */
3807 /*                                                                        */
3808 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3809 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3810 /*                                            resulting in version 6.1    */
3811 /*                                                                        */
3812 /**************************************************************************/
_nx_ppp_lcp_nak_configure_list(NX_PPP * ppp_ptr,UCHAR * naked_list)3813 void  _nx_ppp_lcp_nak_configure_list(NX_PPP *ppp_ptr, UCHAR *naked_list)
3814 {
3815 
3816 UINT    i;
3817 
3818     NX_PARAMETER_NOT_USED(ppp_ptr);
3819 
3820     /* Currently, nothing needs to be done in this routine since the options
3821        we are asking for are basic and must be supported. If additional options
3822        are added, we will need to process the NAK list.  */
3823 
3824     /* Just clear the naked list for now.  */
3825     for(i = 0; i < NX_PPP_OPTION_MESSAGE_LENGTH; i++)
3826         naked_list[i] = 0;
3827 }
3828 
3829 
3830 /**************************************************************************/
3831 /*                                                                        */
3832 /*  FUNCTION                                               RELEASE        */
3833 /*                                                                        */
3834 /*    _nx_ppp_lcp_terminate_ack_send                      PORTABLE C      */
3835 /*                                                           6.1          */
3836 /*  AUTHOR                                                                */
3837 /*                                                                        */
3838 /*    Yuxin Zhou, Microsoft Corporation                                   */
3839 /*                                                                        */
3840 /*  DESCRIPTION                                                           */
3841 /*                                                                        */
3842 /*    This function builds a terminate ACK LCP message and sends it out.  */
3843 /*                                                                        */
3844 /*  INPUT                                                                 */
3845 /*                                                                        */
3846 /*    ppp_ptr                               PPP instance pointer          */
3847 /*                                                                        */
3848 /*  OUTPUT                                                                */
3849 /*                                                                        */
3850 /*    None                                                                */
3851 /*                                                                        */
3852 /*  CALLS                                                                 */
3853 /*                                                                        */
3854 /*    nx_packet_allocate                    Allocate a packet for sending */
3855 /*    _nx_ppp_packet_transmit               Send AHDLC packet             */
3856 /*                                                                        */
3857 /*  CALLED BY                                                             */
3858 /*                                                                        */
3859 /*    _nx_ppp_lcp_state_machine_update      LCP state machine processing  */
3860 /*                                                                        */
3861 /*  RELEASE HISTORY                                                       */
3862 /*                                                                        */
3863 /*    DATE              NAME                      DESCRIPTION             */
3864 /*                                                                        */
3865 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3866 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3867 /*                                            resulting in version 6.1    */
3868 /*                                                                        */
3869 /**************************************************************************/
_nx_ppp_lcp_terminate_ack_send(NX_PPP * ppp_ptr)3870 void  _nx_ppp_lcp_terminate_ack_send(NX_PPP *ppp_ptr)
3871 {
3872 
3873 UINT        status;
3874 NX_PACKET   *packet_ptr;
3875 
3876 
3877     /* Allocate a packet for the PPP packet.  */
3878     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
3879 
3880     /* Determine if the packet was allocated successfully.  */
3881     if (status != NX_SUCCESS)
3882     {
3883 
3884 #ifndef NX_PPP_DISABLE_INFO
3885 
3886         /* Increment the number of packet allocation timeouts.  */
3887         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
3888 #endif
3889 
3890         /* An error was detected, simply return a NULL pointer.  */
3891         return;
3892     }
3893 
3894     /* Build terminate ACK LCP message.  */
3895     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
3896     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_LCP_PROTOCOL & 0xFF;
3897     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_LCP_TERMINATE_ACK;
3898     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_receive_id;
3899     packet_ptr -> nx_packet_prepend_ptr[4] =  0;
3900     packet_ptr -> nx_packet_prepend_ptr[5] =  4;
3901 
3902     /* Setup the append pointer and the packet length.  */
3903     packet_ptr -> nx_packet_length =  6;
3904     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3905 
3906 #ifndef NX_PPP_DISABLE_INFO
3907 
3908     /* Increment the number of LCP frames sent.  */
3909     ppp_ptr -> nx_ppp_lcp_frames_sent++;
3910 
3911     /* Increment the number of LCP terminate ACKs sent.  */
3912     ppp_ptr -> nx_ppp_lcp_terminate_acks_sent++;
3913 #endif
3914 
3915     /* Send the packet out.  */
3916     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
3917 }
3918 
3919 
3920 /**************************************************************************/
3921 /*                                                                        */
3922 /*  FUNCTION                                               RELEASE        */
3923 /*                                                                        */
3924 /*    _nx_ppp_lcp_terminate_request_send                  PORTABLE C      */
3925 /*                                                           6.1          */
3926 /*  AUTHOR                                                                */
3927 /*                                                                        */
3928 /*    Yuxin Zhou, Microsoft Corporation                                   */
3929 /*                                                                        */
3930 /*  DESCRIPTION                                                           */
3931 /*                                                                        */
3932 /*    This function builds a LCP terminate message and sends it out.      */
3933 /*                                                                        */
3934 /*  INPUT                                                                 */
3935 /*                                                                        */
3936 /*    ppp_ptr                               PPP instance pointer          */
3937 /*                                                                        */
3938 /*  OUTPUT                                                                */
3939 /*                                                                        */
3940 /*    None                                                                */
3941 /*                                                                        */
3942 /*  CALLS                                                                 */
3943 /*                                                                        */
3944 /*    nx_packet_allocate                    Allocate a packet for sending */
3945 /*    _nx_ppp_packet_transmit               Send PPP packet               */
3946 /*                                                                        */
3947 /*  CALLED BY                                                             */
3948 /*                                                                        */
3949 /*    _nx_ppp_lcp_state_machine_update      LCP state machine processing  */
3950 /*                                                                        */
3951 /*  RELEASE HISTORY                                                       */
3952 /*                                                                        */
3953 /*    DATE              NAME                      DESCRIPTION             */
3954 /*                                                                        */
3955 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3956 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3957 /*                                            resulting in version 6.1    */
3958 /*                                                                        */
3959 /**************************************************************************/
_nx_ppp_lcp_terminate_request_send(NX_PPP * ppp_ptr)3960 void  _nx_ppp_lcp_terminate_request_send(NX_PPP *ppp_ptr)
3961 {
3962 
3963 UINT        status;
3964 NX_PACKET   *packet_ptr;
3965 
3966     /* Allocate a packet for the PPP packet.  */
3967     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
3968 
3969     /* Determine if the packet was allocated successfully.  */
3970     if (status != NX_SUCCESS)
3971     {
3972 
3973 #ifndef NX_PPP_DISABLE_INFO
3974 
3975         /* Increment the number of packet allocation timeouts.  */
3976         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
3977 #endif
3978 
3979         /* An error was detected, simply return a NULL pointer.  */
3980         return;
3981     }
3982 
3983     /* Build terminate request message.  */
3984     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
3985     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_LCP_PROTOCOL & 0xFF;
3986     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_LCP_TERMINATE_REQUEST;
3987     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_transmit_id;
3988     packet_ptr -> nx_packet_prepend_ptr[4] =  0;
3989     packet_ptr -> nx_packet_prepend_ptr[5] =  4;
3990 
3991     /* Setup the append pointer and the packet length.  */
3992     packet_ptr -> nx_packet_length =  6;
3993     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
3994 
3995 #ifndef NX_PPP_DISABLE_INFO
3996 
3997     /* Increment the number of LCP frames sent.  */
3998     ppp_ptr -> nx_ppp_lcp_frames_sent++;
3999 
4000     /* Increment the number of LCP terminate requests sent.  */
4001     ppp_ptr -> nx_ppp_lcp_terminate_requests_sent++;
4002 #endif
4003 
4004     /* Send terminate request.  */
4005     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
4006 }
4007 
4008 
4009 #ifndef NX_PPP_DISABLE_PAP
4010 /**************************************************************************/
4011 /*                                                                        */
4012 /*  FUNCTION                                               RELEASE        */
4013 /*                                                                        */
4014 /*    _nx_ppp_pap_state_machine_update                    PORTABLE C      */
4015 /*                                                           6.1          */
4016 /*  AUTHOR                                                                */
4017 /*                                                                        */
4018 /*    Yuxin Zhou, Microsoft Corporation                                   */
4019 /*                                                                        */
4020 /*  DESCRIPTION                                                           */
4021 /*                                                                        */
4022 /*    This function processes events and state changes in the PPP PAP     */
4023 /*    state machine.                                                      */
4024 /*                                                                        */
4025 /*  INPUT                                                                 */
4026 /*                                                                        */
4027 /*    ppp_ptr                               PPP instance pointer          */
4028 /*    packet_ptr                            Pointer to PAP packet         */
4029 /*                                                                        */
4030 /*  OUTPUT                                                                */
4031 /*                                                                        */
4032 /*    None                                                                */
4033 /*                                                                        */
4034 /*  CALLS                                                                 */
4035 /*                                                                        */
4036 /*    _nx_ppp_pap_login_valid               Check for valid peer login    */
4037 /*    _nx_ppp_pap_authentication_request    Send authentication request   */
4038 /*    _nx_ppp_pap_authentication_ack        Send authentication ACK       */
4039 /*    _nx_ppp_pap_authentication_nak        Send authentication NAK       */
4040 /*                                                                        */
4041 /*  CALLED BY                                                             */
4042 /*                                                                        */
4043 /*    _nx_ppp_receive_packet_process        Receive PPP packet processing */
4044 /*    _nx_ppp_timeout                       PPP timeout                   */
4045 /*                                                                        */
4046 /*  RELEASE HISTORY                                                       */
4047 /*                                                                        */
4048 /*    DATE              NAME                      DESCRIPTION             */
4049 /*                                                                        */
4050 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4051 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4052 /*                                            resulting in version 6.1    */
4053 /*                                                                        */
4054 /**************************************************************************/
_nx_ppp_pap_state_machine_update(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)4055 void _nx_ppp_pap_state_machine_update(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
4056 {
4057 
4058 UCHAR       code;
4059 UINT        valid;
4060 
4061 
4062     /* Determine if a packet is present. If so, drive the event from the packet.  */
4063     if (packet_ptr)
4064     {
4065 
4066 #ifndef NX_PPP_DISABLE_INFO
4067 
4068         /* Increment the number of PAP frames received.  */
4069         ppp_ptr -> nx_ppp_pap_frames_received++;
4070 #endif
4071 
4072         /* Pickup the type of received PAP code.  */
4073         code =  packet_ptr -> nx_packet_prepend_ptr[2];
4074 
4075         /* Remember receive id.  */
4076         ppp_ptr -> nx_ppp_receive_id =  packet_ptr -> nx_packet_prepend_ptr[3];
4077 
4078         /* Check the incoming code.  */
4079         if ((code < NX_PPP_PAP_AUTHENTICATE_REQUEST) || (code > NX_PPP_PAP_AUTHENTICATE_NAK))
4080         {
4081 
4082 #ifndef NX_PPP_DISABLE_INFO
4083 
4084             /* Increment the number of internal errors.  */
4085             ppp_ptr -> nx_ppp_internal_errors++;
4086 
4087             /* Increment the PAP unknown requests counter.  */
4088             ppp_ptr -> nx_ppp_pap_unknown_requests_received++;
4089 #endif
4090             return;
4091         }
4092     }
4093     else
4094     {
4095 
4096         /* Set the code to timeout.  */
4097         code =   NX_PPP_PAP_AUTHENTICATE_TIMEOUT;
4098     }
4099 
4100 #ifndef NX_PPP_DISABLE_INFO
4101 
4102     /* Increment the appropriate counter.  */
4103     switch (code)
4104     {
4105 
4106     case NX_PPP_PAP_AUTHENTICATE_REQUEST:
4107 
4108         /* Increment the authenticate requests counter.  */
4109         ppp_ptr -> nx_ppp_pap_authenticate_requests_received++;
4110         break;
4111 
4112     case NX_PPP_PAP_AUTHENTICATE_ACK:
4113 
4114         /* Increment the authenticate acks counter.  */
4115         ppp_ptr -> nx_ppp_pap_authenticate_acks_received++;
4116         break;
4117 
4118     case NX_PPP_PAP_AUTHENTICATE_NAK:
4119 
4120         /* Increment the authenticate naks counter.  */
4121         ppp_ptr -> nx_ppp_pap_authenticate_naks_received++;
4122         break;
4123 
4124     case NX_PPP_PAP_AUTHENTICATE_TIMEOUT:
4125 
4126         /* Determine if we are in the initial state. If so, this really isn't a timeout.  */
4127         if (ppp_ptr -> nx_ppp_pap_state != NX_PPP_PAP_START_STATE)
4128         {
4129 
4130             /* Increment the authenticate timeout counter.  */
4131             ppp_ptr -> nx_ppp_pap_state_machine_timeouts++;
4132         }
4133         break;
4134     }
4135 #endif
4136 
4137     /* Process relative to the current state.  */
4138     switch (ppp_ptr -> nx_ppp_pap_state)
4139     {
4140 
4141         /* Starting state.  */
4142         case NX_PPP_PAP_START_STATE:
4143         {
4144 
4145             /* Determine if we need to generate a login for the peer to verify.  */
4146             if (ppp_ptr -> nx_ppp_generate_authentication_protocol)
4147             {
4148 
4149                 /* Setup the retry counter.  */
4150                 ppp_ptr -> nx_ppp_protocol_retry_counter =  0;
4151 
4152                 /* Setup the timeout.  */
4153                 ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
4154 
4155                 /* Generate PAP login request and send to the peer.  */
4156                 _nx_ppp_pap_authentication_request(ppp_ptr);
4157 
4158                 /* Move to the authenticate request sent state.  */
4159                 ppp_ptr -> nx_ppp_pap_state =  NX_PPP_PAP_AUTHENTICATE_REQUEST_SENT_STATE;
4160             }
4161             else
4162             {
4163 
4164                 /* Move to the authenticate wait state.  */
4165                 ppp_ptr -> nx_ppp_pap_state =  NX_PPP_PAP_AUTHENTICATE_REQUEST_WAIT_STATE;
4166             }
4167             break;
4168         }
4169 
4170         case NX_PPP_PAP_AUTHENTICATE_REQUEST_SENT_STATE:
4171         {
4172 
4173             /* In this state, this peer has sent an authentication request and is waiting for
4174                an ACK or NAK from the peer.  */
4175             if ((code == NX_PPP_PAP_AUTHENTICATE_REQUEST) && (packet_ptr))
4176             {
4177 
4178                 /* Determine if the login information is valid.  */
4179                 valid =  _nx_ppp_pap_login_valid(ppp_ptr, packet_ptr);
4180 
4181                 /* Is the login valid?  */
4182                 if (valid == NX_TRUE)
4183                 {
4184 
4185                     /* Send an ACK message.  */
4186                     _nx_ppp_pap_authentication_ack(ppp_ptr);
4187 
4188                     /* Now determine if we need to authenticate ourselves.  */
4189                     if (ppp_ptr -> nx_ppp_generate_authentication_protocol != NX_PPP_PAP_PROTOCOL)
4190                     {
4191 
4192                         /* We do not need to authenticate ourselves, so we can move into PAP completed state.  */
4193                         ppp_ptr ->  nx_ppp_pap_state =  NX_PPP_PAP_COMPLETED_STATE;
4194 
4195                         /* Mark the PPP instance as authenticated.  */
4196                         ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
4197 
4198                         /* Turn off the timeout.  */
4199                         ppp_ptr -> nx_ppp_timeout =  0;
4200                     }
4201                 }
4202                 else
4203                 {
4204 
4205                     /* Send NAK to tell peer the authentication failed.  */
4206                     _nx_ppp_pap_authentication_nak(ppp_ptr);
4207 
4208                     /* No state change, just stay here!  */
4209                 }
4210             }
4211 
4212             /* Was a NAK received?  */
4213             else if (code == NX_PPP_PAP_AUTHENTICATE_NAK)
4214             {
4215 
4216                 /* Determine if there is an application NAK callback.  */
4217                 if (ppp_ptr -> nx_ppp_nak_authentication_notify)
4218                 {
4219 
4220                     /* Yes, call the application's authentication NAK notify callback function.  */
4221                     (ppp_ptr -> nx_ppp_nak_authentication_notify)();
4222                 }
4223 
4224                 /* Generate a new PAP login request and send to the peer.  */
4225                 _nx_ppp_pap_authentication_request(ppp_ptr);
4226             }
4227 
4228             /* Was an ACK received?  */
4229             else if (code == NX_PPP_PAP_AUTHENTICATE_ACK)
4230             {
4231 
4232                 /* Determine if this peer requires authentication.  */
4233                 if (ppp_ptr -> nx_ppp_pap_verify_login)
4234                 {
4235 
4236                     /* Yes, we require PAP verification so move to the request wait state.  */
4237                     ppp_ptr -> nx_ppp_pap_state =  NX_PPP_PAP_AUTHENTICATE_REQUEST_WAIT_STATE;
4238                 }
4239                 else
4240                 {
4241 
4242                     /* Otherwise, we have completed the PAP authentication. Move to the completed
4243                        state. */
4244                     ppp_ptr -> nx_ppp_pap_state =  NX_PPP_PAP_COMPLETED_STATE;
4245 
4246                     /* Mark the PPP instance as authenticated.  */
4247                     ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
4248 
4249                     /* Turn off the timeout.  */
4250                     ppp_ptr -> nx_ppp_timeout =  0;
4251                 }
4252             }
4253 
4254             /* Was a timeout received?  */
4255             else if (code == NX_PPP_PAP_AUTHENTICATE_TIMEOUT)
4256             {
4257 
4258                 /* Increment the retry counter.  */
4259                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
4260 
4261                 /* Determine if the PAP retry counter has been exceeded.  */
4262                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_PAP_PROTOCOL_RETRIES)
4263                 {
4264 
4265                     /* Setup the timeout.  */
4266                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
4267 
4268                     /* Generate a new PAP login request and send to the peer.  */
4269                     _nx_ppp_pap_authentication_request(ppp_ptr);
4270                 }
4271                 else
4272                 {
4273 
4274                     /* Retry counter exceeded.  */
4275 
4276                     /* Enter PAP failed state.  PPP must be stopped and started to try again.  */
4277                     ppp_ptr -> nx_ppp_pap_state =  NX_PPP_PAP_FAILED_STATE;
4278 
4279                     /* Determine if the application has registered a link down notification
4280                        callback.  */
4281                     if (ppp_ptr -> nx_ppp_link_down_callback)
4282                     {
4283 
4284                         /* Yes, call the application's callback function.  */
4285                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
4286                     }
4287                 }
4288             }
4289 #ifndef NX_PPP_DISABLE_INFO
4290             else
4291             {
4292 
4293                 /* Increment the number of unhandled state machine events.   */
4294                 ppp_ptr -> nx_ppp_pap_state_machine_unhandled_requests++;
4295             }
4296 #endif
4297 
4298             break;
4299         }
4300 
4301         case NX_PPP_PAP_AUTHENTICATE_REQUEST_WAIT_STATE:
4302         {
4303 
4304             /* In this state, this peer must send an authenticate request.  There is no
4305                authentication required by the peer.  */
4306             if ((code == NX_PPP_PAP_AUTHENTICATE_REQUEST) && (packet_ptr))
4307             {
4308 
4309                 /* Determine if the login information is valid.  */
4310                 valid =  _nx_ppp_pap_login_valid(ppp_ptr, packet_ptr);
4311 
4312                 /* Is the login valid?  */
4313                 if (valid == NX_TRUE)
4314                 {
4315 
4316                     /* Send an ACK message.  */
4317                     _nx_ppp_pap_authentication_ack(ppp_ptr);
4318 
4319                     /* No authentication is required by peer, so we can move into PAP completed state.  */
4320                     ppp_ptr ->  nx_ppp_pap_state =  NX_PPP_PAP_COMPLETED_STATE;
4321 
4322                     /* Mark the PPP instance as authenticated.  */
4323                     ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
4324 
4325                     /* Turn off the timeout.  */
4326                     ppp_ptr -> nx_ppp_timeout =  0;
4327                 }
4328                 else
4329                 {
4330 
4331                     /* Send NAK to tell peer the authentication failed.  */
4332                     _nx_ppp_pap_authentication_nak(ppp_ptr);
4333 
4334                     /* No state change, just stay here!  */
4335                 }
4336             }
4337 #ifndef NX_PPP_DISABLE_INFO
4338             else
4339             {
4340 
4341                 /* Increment the number of unhandled state machine events.   */
4342                 ppp_ptr -> nx_ppp_pap_state_machine_unhandled_requests++;
4343             }
4344 #endif
4345         break;
4346     }
4347 
4348     default:
4349 #ifndef NX_PPP_DISABLE_INFO
4350         {
4351 
4352             /* Increment the number of unhandled state machine events.   */
4353             ppp_ptr -> nx_ppp_pap_state_machine_unhandled_requests++;
4354         }
4355 #endif
4356         break;
4357     }
4358 }
4359 
4360 
4361 /**************************************************************************/
4362 /*                                                                        */
4363 /*  FUNCTION                                               RELEASE        */
4364 /*                                                                        */
4365 /*    _nx_ppp_pap_authentication_request                  PORTABLE C      */
4366 /*                                                           6.1          */
4367 /*  AUTHOR                                                                */
4368 /*                                                                        */
4369 /*    Yuxin Zhou, Microsoft Corporation                                   */
4370 /*                                                                        */
4371 /*  DESCRIPTION                                                           */
4372 /*                                                                        */
4373 /*    This function builds and sends an authentication request message    */
4374 /*    the peer. The peer will then either ACK or NAK the request.         */
4375 /*                                                                        */
4376 /*  INPUT                                                                 */
4377 /*                                                                        */
4378 /*    ppp_ptr                               PPP instance pointer          */
4379 /*                                                                        */
4380 /*  OUTPUT                                                                */
4381 /*                                                                        */
4382 /*    None                                                                */
4383 /*                                                                        */
4384 /*  CALLS                                                                 */
4385 /*                                                                        */
4386 /*    nx_packet_allocate                    Allocate packet               */
4387 /*    (nx_ppp_pap_generate_login)           Pickup name and password      */
4388 /*    _nx_ppp_packet_transmit               Send PAP response             */
4389 /*    _nx_utility_string_length_check       Check string length           */
4390 /*                                                                        */
4391 /*  CALLED BY                                                             */
4392 /*                                                                        */
4393 /*    _nx_ppp_pap_state_machine_update      PPP state machine update      */
4394 /*                                                                        */
4395 /*  RELEASE HISTORY                                                       */
4396 /*                                                                        */
4397 /*    DATE              NAME                      DESCRIPTION             */
4398 /*                                                                        */
4399 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4400 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4401 /*                                            resulting in version 6.1    */
4402 /*                                                                        */
4403 /**************************************************************************/
_nx_ppp_pap_authentication_request(NX_PPP * ppp_ptr)4404 void _nx_ppp_pap_authentication_request(NX_PPP *ppp_ptr)
4405 {
4406 
4407 UINT        length, password_length, i, j;
4408 UCHAR       name[NX_PPP_NAME_SIZE + 1];
4409 UCHAR       password[NX_PPP_PASSWORD_SIZE + 1];
4410 UINT        status;
4411 NX_PACKET   *packet_ptr;
4412 
4413 
4414     /* Initialize name and password.  */
4415     name[0] =  0;
4416     password[0] =  0;
4417 
4418     /* Determine if there is a login name/password generation routine.  */
4419     if (ppp_ptr -> nx_ppp_pap_generate_login)
4420     {
4421 
4422         /* Get the name and password */
4423         ppp_ptr -> nx_ppp_pap_generate_login((CHAR *) name, (CHAR *) password);
4424     }
4425 
4426     /* Allocate a packet for the PPP PAP response packet.  */
4427     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
4428 
4429     /* Determine if the packet was allocated successfully.  */
4430     if (status != NX_SUCCESS)
4431     {
4432 
4433 #ifndef NX_PPP_DISABLE_INFO
4434 
4435         /* Increment the number of packet allocation timeouts.  */
4436         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
4437 #endif
4438 
4439         /* An error was detected, simply return a NULL pointer.  */
4440         return;
4441     }
4442 
4443     /* Calculate the size of the name and password.  */
4444     if (_nx_utility_string_length_check((CHAR *)name, &length, NX_PPP_NAME_SIZE) ||
4445         _nx_utility_string_length_check((CHAR *)password, &password_length, NX_PPP_PASSWORD_SIZE))
4446     {
4447 
4448         /* Release the packet.  */
4449         nx_packet_release(packet_ptr);
4450         return;
4451     }
4452 
4453     /* Check if out of boundary.  */
4454     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(length + 1 + password_length + 1 + 6))
4455     {
4456 
4457         /* Release the packet.  */
4458         nx_packet_release(packet_ptr);
4459         return;
4460     }
4461 
4462     /* Set PAP authentication request, ID, and length.  */
4463     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
4464     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_PAP_PROTOCOL & 0xFF;
4465     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_PAP_AUTHENTICATE_REQUEST;
4466     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_transmit_id; /* ID */
4467 
4468     /* Setup the length.  */
4469     packet_ptr -> nx_packet_prepend_ptr[4] =  (UCHAR) (((length) + 1 + (password_length) + 1 + 4) >> 8);
4470     packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR) (((length) + 1 + (password_length) + 1 + 4) & 0xFF);
4471 
4472     /* Store the PAP name.  */
4473     packet_ptr -> nx_packet_prepend_ptr[6] =  (UCHAR)(length & 0xFF);
4474     for (i = 0; i < length; i++)
4475     {
4476 
4477         /* Store byte of name.  */
4478         packet_ptr -> nx_packet_prepend_ptr[i+7] =  name[i];
4479     }
4480 
4481     /* Store PAP password.  */
4482     packet_ptr -> nx_packet_prepend_ptr[i+7] =  (password_length & 0xFF);
4483     for (j = 0; j < password_length; j++)
4484     {
4485 
4486         /* Store byte of name.  */
4487         packet_ptr -> nx_packet_prepend_ptr[j+i+8] =  password[j];
4488     }
4489 
4490     /* Setup the append pointer and the packet length.  */
4491     packet_ptr -> nx_packet_length =  (length) + 1 + (password_length) + 1 + 4 + 2;
4492     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
4493 
4494 #ifndef NX_PPP_DISABLE_INFO
4495 
4496     /* Increment the number of PAP frames sent.  */
4497     ppp_ptr -> nx_ppp_pap_frames_sent++;
4498 
4499     /* Increment the authentication requests sent counter.  */
4500     ppp_ptr -> nx_ppp_pap_authenticate_requests_sent++;
4501 #endif
4502 
4503     /* Send the PAP request.  */
4504     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
4505 }
4506 
4507 
4508 /**************************************************************************/
4509 /*                                                                        */
4510 /*  FUNCTION                                               RELEASE        */
4511 /*                                                                        */
4512 /*    _nx_ppp_pap_login_valid                             PORTABLE C      */
4513 /*                                                           6.1          */
4514 /*  AUTHOR                                                                */
4515 /*                                                                        */
4516 /*    Yuxin Zhou, Microsoft Corporation                                   */
4517 /*                                                                        */
4518 /*  DESCRIPTION                                                           */
4519 /*                                                                        */
4520 /*    This function validates the login information supplied by the       */
4521 /*    peer.                                                               */
4522 /*                                                                        */
4523 /*  INPUT                                                                 */
4524 /*                                                                        */
4525 /*    ppp_ptr                               PPP instance pointer          */
4526 /*    packet_ptr                            Pointer to PAP packet         */
4527 /*                                                                        */
4528 /*  OUTPUT                                                                */
4529 /*                                                                        */
4530 /*    NX_TRUE                               Valid login                   */
4531 /*    NX_FALSE                              Invalid login                 */
4532 /*                                                                        */
4533 /*  CALLS                                                                 */
4534 /*                                                                        */
4535 /*    (nx_ppp_pap_verify_login)             Verify name and password      */
4536 /*                                                                        */
4537 /*  CALLED BY                                                             */
4538 /*                                                                        */
4539 /*    _nx_ppp_pap_state_machine_update      PAP state machine update      */
4540 /*                                                                        */
4541 /*  RELEASE HISTORY                                                       */
4542 /*                                                                        */
4543 /*    DATE              NAME                      DESCRIPTION             */
4544 /*                                                                        */
4545 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4546 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4547 /*                                            resulting in version 6.1    */
4548 /*                                                                        */
4549 /**************************************************************************/
_nx_ppp_pap_login_valid(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)4550 UINT _nx_ppp_pap_login_valid(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
4551 {
4552 
4553 UCHAR   length, password_length, i, j;
4554 UCHAR   name[NX_PPP_NAME_SIZE + 1];
4555 UCHAR   password[NX_PPP_PASSWORD_SIZE + 1];
4556 UINT    status;
4557 
4558 
4559     /* Get the name length.  */
4560     length =  packet_ptr -> nx_packet_prepend_ptr[6];
4561 
4562     /* Check for valid packet length.  */
4563     if ((ULONG)(length + 7) > packet_ptr -> nx_packet_length)
4564     {
4565         return(NX_FALSE);
4566     }
4567 
4568     /* Determine if the length is greater than the name size.  */
4569     if (length > NX_PPP_NAME_SIZE)
4570     {
4571 
4572 #ifndef NX_PPP_DISABLE_INFO
4573 
4574         /* Increment the number of internal errors.  */
4575         ppp_ptr -> nx_ppp_internal_errors++;
4576 #endif
4577         return(NX_FALSE);
4578     }
4579 
4580     /* Get the name.  */
4581     for(i = 0; i < length; i++)
4582     {
4583 
4584         /* Get a character of the name.  */
4585         name[i] =  packet_ptr -> nx_packet_prepend_ptr[i+7];
4586     }
4587 
4588     /* Null terminate the name.  */
4589     name[i] = 0;
4590 
4591     /* Get length of password.  */
4592     password_length =  packet_ptr -> nx_packet_prepend_ptr[i+7];
4593 
4594     /* Check for valid packet length.  */
4595     if ((ULONG)(password_length + i + 8) > packet_ptr -> nx_packet_length)
4596     {
4597         return(NX_FALSE);
4598     }
4599 
4600     /* Determine if the length is greater than the password size.  */
4601     if (password_length > NX_PPP_PASSWORD_SIZE)
4602     {
4603 
4604 #ifndef NX_PPP_DISABLE_INFO
4605 
4606         /* Increment the number of internal errors.  */
4607         ppp_ptr -> nx_ppp_internal_errors++;
4608 #endif
4609 
4610         return(NX_FALSE);
4611     }
4612 
4613     /* Get the password.  */
4614     for(j = 0; j < password_length; j++)
4615     {
4616 
4617         /* Get a character of the password.  */
4618         password[j] =  packet_ptr -> nx_packet_prepend_ptr[j+i+8];
4619     }
4620 
4621     /* Null terminate the password.  */
4622     password[j] = 0;
4623 
4624     /* Determine if there is an authentication routine.  */
4625     if (ppp_ptr -> nx_ppp_pap_verify_login)
4626     {
4627 
4628         /* Call the user supplied PAP authentication routine.  */
4629         status =  ppp_ptr -> nx_ppp_pap_verify_login((CHAR *) name, (CHAR *) password);
4630 
4631         /* Check to see if it is valid.  */
4632         if (status)
4633         {
4634 
4635             /* Return NX_FALSE, which indicates the password is invalid.  */
4636             return (NX_FALSE);
4637         }
4638     }
4639 
4640     /* Return NX_TRUE.  */
4641     return(NX_TRUE);
4642 }
4643 
4644 
4645 /**************************************************************************/
4646 /*                                                                        */
4647 /*  FUNCTION                                               RELEASE        */
4648 /*                                                                        */
4649 /*    _nx_ppp_pap_authentication_ack                      PORTABLE C      */
4650 /*                                                           6.1          */
4651 /*  AUTHOR                                                                */
4652 /*                                                                        */
4653 /*    Yuxin Zhou, Microsoft Corporation                                   */
4654 /*                                                                        */
4655 /*  DESCRIPTION                                                           */
4656 /*                                                                        */
4657 /*    This function builds and sends an authentication ACK message to     */
4658 /*    the peer in response to the peer's authentication request.          */
4659 /*                                                                        */
4660 /*  INPUT                                                                 */
4661 /*                                                                        */
4662 /*    ppp_ptr                               PPP instance pointer          */
4663 /*                                                                        */
4664 /*  OUTPUT                                                                */
4665 /*                                                                        */
4666 /*    None                                                                */
4667 /*                                                                        */
4668 /*  CALLS                                                                 */
4669 /*                                                                        */
4670 /*    nx_packet_allocate                    Allocate packet               */
4671 /*    _nx_ppp_packet_transmit               Send PAP response             */
4672 /*                                                                        */
4673 /*  CALLED BY                                                             */
4674 /*                                                                        */
4675 /*    _nx_ppp_pap_state_machine_update      PPP state machine update      */
4676 /*                                                                        */
4677 /*  RELEASE HISTORY                                                       */
4678 /*                                                                        */
4679 /*    DATE              NAME                      DESCRIPTION             */
4680 /*                                                                        */
4681 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4682 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4683 /*                                            resulting in version 6.1    */
4684 /*                                                                        */
4685 /**************************************************************************/
_nx_ppp_pap_authentication_ack(NX_PPP * ppp_ptr)4686 void  _nx_ppp_pap_authentication_ack(NX_PPP *ppp_ptr)
4687 {
4688 
4689 UINT        status;
4690 NX_PACKET   *packet_ptr;
4691 
4692 
4693     /* Allocate a packet for the PPP PAP response packet.  */
4694     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
4695 
4696     /* Determine if the packet was allocated successfully.  */
4697     if (status != NX_SUCCESS)
4698     {
4699 
4700 #ifndef NX_PPP_DISABLE_INFO
4701 
4702         /* Increment the number of packet allocation timeouts.  */
4703         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
4704 #endif
4705 
4706         /* An error was detected, simply return a NULL pointer.  */
4707         return;
4708     }
4709 
4710     /* Build the PAP ACK response message.  */
4711     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
4712     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_PAP_PROTOCOL & 0xFF;
4713     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_PAP_AUTHENTICATE_ACK;
4714     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_receive_id;
4715     packet_ptr -> nx_packet_prepend_ptr[4] =  0;
4716     packet_ptr -> nx_packet_prepend_ptr[5] =  5;
4717     packet_ptr -> nx_packet_prepend_ptr[6] =  0;
4718 
4719     /* Setup the append pointer and the packet length.  */
4720     packet_ptr -> nx_packet_length =  7;
4721     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
4722 
4723     /* Set the authenticated flag to true.  */
4724     ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
4725 
4726 #ifndef NX_PPP_DISABLE_INFO
4727 
4728     /* Increment the number of PAP frames sent.  */
4729     ppp_ptr -> nx_ppp_pap_frames_sent++;
4730 
4731     /* Increment the number of authentication ACKs sent counter.  */
4732     ppp_ptr -> nx_ppp_pap_authenticate_acks_sent++;
4733 #endif
4734 
4735     /* Send the ACK message out.  */
4736     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
4737 }
4738 
4739 
4740 /**************************************************************************/
4741 /*                                                                        */
4742 /*  FUNCTION                                               RELEASE        */
4743 /*                                                                        */
4744 /*    _nx_ppp_pap_authentication_nak                      PORTABLE C      */
4745 /*                                                           6.1          */
4746 /*  AUTHOR                                                                */
4747 /*                                                                        */
4748 /*    Yuxin Zhou, Microsoft Corporation                                   */
4749 /*                                                                        */
4750 /*  DESCRIPTION                                                           */
4751 /*                                                                        */
4752 /*    This function builds and sends an authentication NAK message to     */
4753 /*    the peer in response to the peer's authentication request.          */
4754 /*                                                                        */
4755 /*  INPUT                                                                 */
4756 /*                                                                        */
4757 /*    ppp_ptr                               PPP instance pointer          */
4758 /*                                                                        */
4759 /*  OUTPUT                                                                */
4760 /*                                                                        */
4761 /*    None                                                                */
4762 /*                                                                        */
4763 /*  CALLS                                                                 */
4764 /*                                                                        */
4765 /*    nx_packet_allocate                    Allocate packet               */
4766 /*    _nx_ppp_packet_transmit               Send PAP response             */
4767 /*                                                                        */
4768 /*  CALLED BY                                                             */
4769 /*                                                                        */
4770 /*    _nx_ppp_pap_state_machine_update      PPP state machine update      */
4771 /*                                                                        */
4772 /*  RELEASE HISTORY                                                       */
4773 /*                                                                        */
4774 /*    DATE              NAME                      DESCRIPTION             */
4775 /*                                                                        */
4776 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4777 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4778 /*                                            resulting in version 6.1    */
4779 /*                                                                        */
4780 /**************************************************************************/
_nx_ppp_pap_authentication_nak(NX_PPP * ppp_ptr)4781 void _nx_ppp_pap_authentication_nak(NX_PPP *ppp_ptr)
4782 {
4783 
4784 UINT        status;
4785 NX_PACKET   *packet_ptr;
4786 
4787 
4788     /* Allocate a packet for the PPP PAP response packet.  */
4789     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
4790 
4791     /* Determine if the packet was allocated successfully.  */
4792     if (status != NX_SUCCESS)
4793     {
4794 
4795 #ifndef NX_PPP_DISABLE_INFO
4796 
4797         /* Increment the number of packet allocation timeouts.  */
4798         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
4799 #endif
4800 
4801         /* An error was detected, simply return a NULL pointer.  */
4802         return;
4803     }
4804 
4805     /* Build the PAP ACK response message.  */
4806     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_PAP_PROTOCOL & 0xFF00) >> 8;
4807     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_PAP_PROTOCOL & 0xFF;
4808     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_PAP_AUTHENTICATE_NAK;
4809     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_receive_id;
4810     packet_ptr -> nx_packet_prepend_ptr[4] =  0;
4811     packet_ptr -> nx_packet_prepend_ptr[5] =  5;
4812     packet_ptr -> nx_packet_prepend_ptr[6] =  0;
4813 
4814     /* Setup the append pointer and the packet length.  */
4815     packet_ptr -> nx_packet_length =  7;
4816     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
4817 
4818 
4819 #ifndef NX_PPP_DISABLE_INFO
4820 
4821     /* Increment the number of PAP frames sent.  */
4822     ppp_ptr -> nx_ppp_pap_frames_sent++;
4823 
4824     /* Increment the authentication NAKs sent counter.  */
4825     ppp_ptr -> nx_ppp_pap_authenticate_naks_sent++;
4826 #endif
4827 
4828     /* Send the authentication NAK message out.  */
4829     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
4830 }
4831 
4832 #endif
4833 
4834 
4835 #ifndef NX_PPP_DISABLE_CHAP
4836 /**************************************************************************/
4837 /*                                                                        */
4838 /*  FUNCTION                                               RELEASE        */
4839 /*                                                                        */
4840 /*    _nx_ppp_chap_state_machine_update                   PORTABLE C      */
4841 /*                                                           6.1          */
4842 /*  AUTHOR                                                                */
4843 /*                                                                        */
4844 /*    Yuxin Zhou, Microsoft Corporation                                   */
4845 /*                                                                        */
4846 /*  DESCRIPTION                                                           */
4847 /*                                                                        */
4848 /*    This function processes events and state changes in the PPP CHAP    */
4849 /*    state machine.                                                      */
4850 /*                                                                        */
4851 /*  INPUT                                                                 */
4852 /*                                                                        */
4853 /*    ppp_ptr                               PPP instance pointer          */
4854 /*    packet_ptr                            CHAP packet pointer           */
4855 /*                                                                        */
4856 /*  OUTPUT                                                                */
4857 /*                                                                        */
4858 /*    None                                                                */
4859 /*                                                                        */
4860 /*  CALLS                                                                 */
4861 /*                                                                        */
4862 /*    _nx_ppp_chap_challenge_send           Send CHAP challenge to peer   */
4863 /*    _nx_ppp_chap_challenge_respond        Respond to challenge from peer*/
4864 /*    _nx_ppp_chap_challenge_validate       Validate challenge response   */
4865 /*                                            from peer                   */
4866 /*                                                                        */
4867 /*  CALLED BY                                                             */
4868 /*                                                                        */
4869 /*    _nx_ppp_receive_packet_process        Receive PPP packet processing */
4870 /*    _nx_ppp_timeout                       PPP timeout                   */
4871 /*    _nx_ppp_thread_entry                  PPP processing thread         */
4872 /*                                                                        */
4873 /*  RELEASE HISTORY                                                       */
4874 /*                                                                        */
4875 /*    DATE              NAME                      DESCRIPTION             */
4876 /*                                                                        */
4877 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4878 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4879 /*                                            resulting in version 6.1    */
4880 /*                                                                        */
4881 /**************************************************************************/
_nx_ppp_chap_state_machine_update(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)4882 void _nx_ppp_chap_state_machine_update(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
4883 {
4884 
4885 UCHAR       code;
4886 UINT        valid;
4887 
4888 
4889     /* Determine if a packet is present. If so, derive the event from the packet.  */
4890     if (packet_ptr)
4891     {
4892 
4893 #ifndef NX_PPP_DISABLE_INFO
4894 
4895         /* Increment the number of CHAP frames received.  */
4896         ppp_ptr -> nx_ppp_chap_frames_received++;
4897 #endif
4898 
4899         /* Pickup the type of received CHAP code.  */
4900         code =  packet_ptr -> nx_packet_prepend_ptr[2];
4901 
4902         /* Remember receive id.  */
4903         ppp_ptr -> nx_ppp_receive_id =  packet_ptr -> nx_packet_prepend_ptr[3];
4904 
4905         /* Check the incoming code.  */
4906         if ((code < NX_PPP_CHAP_CHALLENGE_REQUEST) || (code > NX_PPP_CHAP_CHALLENGE_FAILURE))
4907         {
4908 
4909 #ifndef NX_PPP_DISABLE_INFO
4910 
4911             /* Increment the number of internal errors.  */
4912             ppp_ptr -> nx_ppp_internal_errors++;
4913 
4914             /* Increment the number of unknown CHAP requests received.  */
4915             ppp_ptr -> nx_ppp_chap_unknown_requests_received++;
4916 #endif
4917             return;
4918         }
4919     }
4920     else
4921     {
4922 
4923         /* Set the code to timeout.  */
4924         code =   NX_PPP_CHAP_CHALLENGE_TIMEOUT;
4925     }
4926 
4927 #ifndef NX_PPP_DISABLE_INFO
4928 
4929     /* Update receive counters.  */
4930     switch (code)
4931     {
4932 
4933     case NX_PPP_CHAP_CHALLENGE_REQUEST:
4934 
4935         /* Increment the number of CHAP challenge requests received.  */
4936         ppp_ptr -> nx_ppp_chap_challenge_requests_received++;
4937         break;
4938 
4939     case NX_PPP_CHAP_CHALLENGE_RESPONSE:
4940 
4941         /* Increment the number of CHAP challenge responses received.  */
4942         ppp_ptr -> nx_ppp_chap_challenge_responses_received++;
4943         break;
4944 
4945     case NX_PPP_CHAP_CHALLENGE_SUCCESS:
4946 
4947         /* Increment the number of CHAP challenge successful notifications received.  */
4948         ppp_ptr -> nx_ppp_chap_challenge_successes_received++;
4949         break;
4950 
4951     case NX_PPP_CHAP_CHALLENGE_FAILURE:
4952 
4953         /* Increment the number of CHAP challenge failures received.  */
4954         ppp_ptr -> nx_ppp_chap_challenge_failures_received++;
4955         break;
4956 
4957     case NX_PPP_CHAP_CHALLENGE_TIMEOUT:
4958 
4959 
4960         /* Determine if we are in the initial state. If so, this really isn't a timeout.  */
4961         if (ppp_ptr -> nx_ppp_chap_state != NX_PPP_CHAP_START_STATE)
4962         {
4963 
4964             /* Increment the number of CHAP timeouts received.  */
4965             ppp_ptr -> nx_ppp_chap_state_machine_timeouts++;
4966         }
4967         break;
4968     }
4969 #endif
4970 
4971     /* Process relative to the current state.  */
4972     switch (ppp_ptr -> nx_ppp_chap_state)
4973     {
4974         /* Starting state.  */
4975         case NX_PPP_CHAP_START_STATE:
4976         {
4977 
4978             /* Determine if we need to challenge the peer.  */
4979             if (ppp_ptr -> nx_ppp_verify_authentication_protocol)
4980             {
4981 
4982                 /* Setup the retry counter.  */
4983                 ppp_ptr -> nx_ppp_protocol_retry_counter =  0;
4984 
4985                 /* Setup the timeout.  */
4986                 ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
4987 
4988                 /* Send challenge request to peer.  */
4989                 _nx_ppp_chap_challenge_send(ppp_ptr);
4990 
4991                 /* Move to the challenge request sent state.  */
4992                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_STATE;
4993             }
4994             else if (ppp_ptr -> nx_ppp_generate_authentication_protocol)
4995             {
4996 
4997                 /* Move to the challenge wait state, since the peer must challenge.  */
4998                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_REQUEST_WAIT_STATE;
4999             }
5000 #ifndef NX_PPP_DISABLE_INFO
5001             else
5002             {
5003 
5004                 /* Increment the number of unhandled state machine events.   */
5005                 ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
5006             }
5007 #endif
5008             break;
5009         }
5010 
5011         case NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_STATE:
5012         {
5013 
5014             /* In this state, this peer has sent a challenge request and is waiting for
5015                response from the peer.  */
5016             if ((code == NX_PPP_CHAP_CHALLENGE_REQUEST) && (packet_ptr))
5017             {
5018 
5019                 /* Generate a challenge response and send it to the peer.  */
5020                 _nx_ppp_chap_challenge_respond(ppp_ptr, packet_ptr);
5021 
5022                 /* Move to the sent both challenge and response sent state.  */
5023                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_BOTH_STATE;
5024             }
5025 
5026             else if ((code == NX_PPP_CHAP_CHALLENGE_RESPONSE) && (packet_ptr))
5027             {
5028 
5029                 /* Determine if the challenge response is valid. Note this function all sends the Success or
5030                    Failure to the peer.  */
5031                 valid =  _nx_ppp_chap_challenge_validate(ppp_ptr, packet_ptr);
5032 
5033                 /* Is the login valid?  */
5034                 if (valid == NX_TRUE)
5035                 {
5036 
5037                     /* Does the peer need to perform an initial challenge?  */
5038                     if (ppp_ptr -> nx_ppp_generate_authentication_protocol)
5039                     {
5040 
5041                         /* Move to the challenge wait state, since the peer must challenge.  */
5042                         ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_REQUEST_WAIT_STATE;
5043                     }
5044                     else
5045                     {
5046 
5047                         /* Since the peer does not need to challenge, the initial CHAP protocol is complete.  */
5048                         ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_COMPLETED_STATE;
5049 
5050                         /* Mark the PPP instance as authenticated.  */
5051                         ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
5052 
5053                         /* Turn off the timeout.  */
5054                         ppp_ptr -> nx_ppp_timeout =  0;
5055                     }
5056                 }
5057                 else
5058                 {
5059 
5060                     /* Determine if there is an application NAK callback.  */
5061                     if (ppp_ptr -> nx_ppp_nak_authentication_notify)
5062                     {
5063 
5064                         /* Yes, call the application's authentication NAK notify callback function.  */
5065                         (ppp_ptr -> nx_ppp_nak_authentication_notify)();
5066                     }
5067 
5068                     /* Enter into a failed state since challenge failed.  */
5069                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5070 
5071                     /* Determine if the application has registered a link down notification
5072                        callback.  */
5073                     if (ppp_ptr -> nx_ppp_link_down_callback)
5074                     {
5075 
5076                         /* Yes, call the application's callback function.  */
5077                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5078                     }
5079                 }
5080             }
5081 
5082             /* Was a timeout received?  */
5083             else if (code == NX_PPP_CHAP_CHALLENGE_TIMEOUT)
5084             {
5085 
5086                 /* Increment the retry counter.  */
5087                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
5088 
5089                 /* Determine if the CHAP retry counter has been exceeded.  */
5090                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_CHAP_PROTOCOL_RETRIES)
5091                 {
5092 
5093                     /* Setup the timeout.  */
5094                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
5095 
5096                      /* Send challenge request to peer.  */
5097                     _nx_ppp_chap_challenge_send(ppp_ptr);
5098                 }
5099                 else
5100                 {
5101 
5102                     /* Retry counter exceeded.  */
5103 
5104                     /* Enter CHAP failed state.  PPP must be stopped and started to try again.  */
5105                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5106 
5107                     /* Determine if the application has registered a link down notification
5108                        callback.  */
5109                     if (ppp_ptr -> nx_ppp_link_down_callback)
5110                     {
5111 
5112                         /* Yes, call the application's callback function.  */
5113                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5114                     }
5115                 }
5116             }
5117 #ifndef NX_PPP_DISABLE_INFO
5118             else
5119             {
5120 
5121                 /* Increment the number of unhandled state machine events.   */
5122                 ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
5123             }
5124 #endif
5125             break;
5126         }
5127 
5128         case NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_BOTH_STATE:
5129         {
5130 
5131             /* In this state, this peer has sent a challenge request and a challenge response and is waiting for
5132                response from the peer.  */
5133             if (code == NX_PPP_CHAP_CHALLENGE_SUCCESS)
5134             {
5135 
5136                 /* Move to the challenge sent received response state, since the original challenge is still pending.  */
5137                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_RESPONDED_STATE;
5138             }
5139 
5140             else if (code == NX_PPP_CHAP_CHALLENGE_FAILURE)
5141             {
5142 
5143                 /* Move to the failed state since our response failed to satisfy the peer's challenge.  */
5144                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5145 
5146                 /* Determine if the application has registered a link down notification
5147                    callback.  */
5148                 if (ppp_ptr -> nx_ppp_link_down_callback)
5149                 {
5150 
5151                     /* Yes, call the application's callback function.  */
5152                     (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5153                 }
5154             }
5155 
5156             else if ((code == NX_PPP_CHAP_CHALLENGE_RESPONSE) && (packet_ptr))
5157             {
5158 
5159                 /* Determine if the challenge response is valid. Note this function all sends the Success or
5160                    Failure to the peer.  */
5161                 valid =  _nx_ppp_chap_challenge_validate(ppp_ptr, packet_ptr);
5162 
5163                 /* Is the login valid?  */
5164                 if (valid == NX_TRUE)
5165                 {
5166 
5167                     /* Does the peer need to perform an initial challenge?  */
5168                     if (ppp_ptr -> nx_ppp_generate_authentication_protocol)
5169                     {
5170 
5171                         /* Move to the challenge wait state, since the peer must challenge.  */
5172                         ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_RESPONSE_WAIT_STATE;
5173                     }
5174                     else
5175                     {
5176 
5177                         /* Since the peer does not need to challenge, the initial CHAP protocol is complete.  */
5178                         ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_COMPLETED_STATE;
5179 
5180                         /* Mark the PPP instance as authenticated.  */
5181                         ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
5182 
5183                         /* Turn off the timeout.  */
5184                         ppp_ptr -> nx_ppp_timeout =  0;
5185                     }
5186                 }
5187                 else
5188                 {
5189 
5190                     /* Enter into a failed state since challenge failed.  */
5191                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5192 
5193                     /* Determine if the application has registered a link down notification
5194                        callback.  */
5195                     if (ppp_ptr -> nx_ppp_link_down_callback)
5196                     {
5197 
5198                         /* Yes, call the application's callback function.  */
5199                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5200                     }
5201                 }
5202             }
5203 
5204             /* Was a timeout received?  */
5205             else if (code == NX_PPP_CHAP_CHALLENGE_TIMEOUT)
5206             {
5207 
5208                 /* Increment the retry counter.  */
5209                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
5210 
5211                 /* Determine if the CHAP retry counter has been exceeded.  */
5212                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_CHAP_PROTOCOL_RETRIES)
5213                 {
5214 
5215                     /* Setup the timeout.  */
5216                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
5217 
5218                      /* Send challenge request to peer.  */
5219                     _nx_ppp_chap_challenge_send(ppp_ptr);
5220                 }
5221                 else
5222                 {
5223 
5224                     /* Retry counter exceeded.  */
5225 
5226                     /* Enter CHAP failed state.  PPP must be stopped and started to try again.  */
5227                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5228 
5229                     /* Determine if the application has registered a link down notification
5230                        callback.  */
5231                     if (ppp_ptr -> nx_ppp_link_down_callback)
5232                     {
5233 
5234                         /* Yes, call the application's callback function.  */
5235                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5236                     }
5237                 }
5238             }
5239 #ifndef NX_PPP_DISABLE_INFO
5240             else
5241             {
5242 
5243                 /* Increment the number of unhandled state machine events.   */
5244                 ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
5245             }
5246 #endif
5247             break;
5248         }
5249 
5250         case NX_PPP_CHAP_CHALLENGE_REQUEST_SENT_RESPONDED_STATE:
5251         {
5252 
5253             /* In this state, we have already successfully responded to a challenge from the peer
5254                but are still waiting for the initial reply from the peer to our challenge request.  */
5255             if ((code == NX_PPP_CHAP_CHALLENGE_RESPONSE) && (packet_ptr))
5256             {
5257 
5258                 /* Determine if the challenge response is valid. Note this function all sends the Success or
5259                    Failure to the peer.  */
5260                 valid =  _nx_ppp_chap_challenge_validate(ppp_ptr, packet_ptr);
5261 
5262                 /* Is the login valid?  */
5263                 if (valid == NX_TRUE)
5264                 {
5265 
5266                     /* Since the peer does not need to challenge, the initial CHAP protocol is complete.  */
5267                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_COMPLETED_STATE;
5268 
5269                     /* Mark the PPP instance as authenticated.  */
5270                     ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
5271 
5272                     /* Turn off the timeout.  */
5273                     ppp_ptr -> nx_ppp_timeout =  0;
5274                 }
5275                 else
5276                 {
5277 
5278                     /* Enter into a failed state since challenge failed.  */
5279                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5280 
5281                     /* Determine if the application has registered a link down notification
5282                        callback.  */
5283                     if (ppp_ptr -> nx_ppp_link_down_callback)
5284                     {
5285 
5286                         /* Yes, call the application's callback function.  */
5287                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5288                     }
5289                 }
5290             }
5291 
5292             /* Was a timeout received?  */
5293             else if (code == NX_PPP_CHAP_CHALLENGE_TIMEOUT)
5294             {
5295 
5296                 /* Increment the retry counter.  */
5297                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
5298 
5299                 /* Determine if the CHAP retry counter has been exceeded.  */
5300                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_CHAP_PROTOCOL_RETRIES)
5301                 {
5302 
5303                     /* Setup the timeout.  */
5304                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
5305 
5306                      /* Send challenge request to peer.  */
5307                     _nx_ppp_chap_challenge_send(ppp_ptr);
5308                 }
5309                 else
5310                 {
5311 
5312                     /* Retry counter exceeded.  */
5313 
5314                     /* Enter CHAP failed state.  PPP must be stopped and started to try again.  */
5315                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5316 
5317                     /* Determine if the application has registered a link down notification
5318                        callback.  */
5319                     if (ppp_ptr -> nx_ppp_link_down_callback)
5320                     {
5321 
5322                         /* Yes, call the application's callback function.  */
5323                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5324                     }
5325                 }
5326             }
5327 #ifndef NX_PPP_DISABLE_INFO
5328             else
5329             {
5330 
5331                 /* Increment the number of unhandled state machine events.   */
5332                 ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
5333             }
5334 #endif
5335             break;
5336         }
5337 
5338         case NX_PPP_CHAP_CHALLENGE_REQUEST_WAIT_STATE:
5339         {
5340 
5341             /* In this state we only need the challenge from peer, either this peer doesn't challenge or
5342                the initial challenge has already successfully completed.  */
5343             if ((code == NX_PPP_CHAP_CHALLENGE_REQUEST) && (packet_ptr))
5344             {
5345 
5346                 /* Generate a challenge response and send it to the peer.  */
5347                 _nx_ppp_chap_challenge_respond(ppp_ptr, packet_ptr);
5348 
5349                 /* Move to the wait for challenge response state.  */
5350                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_RESPONSE_WAIT_STATE;
5351             }
5352 #ifndef NX_PPP_DISABLE_INFO
5353             else
5354             {
5355 
5356                 /* Increment the number of unhandled state machine events.   */
5357                 ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
5358             }
5359 #endif
5360             break;
5361         }
5362 
5363         case NX_PPP_CHAP_CHALLENGE_RESPONSE_WAIT_STATE:
5364         {
5365 
5366             /* In this state, this peer has sent a challenge response and is waiting for
5367                response from the peer.  */
5368             if (code == NX_PPP_CHAP_CHALLENGE_SUCCESS)
5369             {
5370 
5371                 /* Since the peer does not need to challenge, the initial CHAP protocol is complete.  */
5372                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_COMPLETED_STATE;
5373 
5374                 /* Mark the PPP instance as authenticated.  */
5375                 ppp_ptr -> nx_ppp_authenticated =  NX_TRUE;
5376 
5377                 /* Turn off the timeout.  */
5378                 ppp_ptr -> nx_ppp_timeout =  0;
5379             }
5380 
5381             else if (code == NX_PPP_CHAP_CHALLENGE_FAILURE)
5382             {
5383 
5384                 /* Move to the failed state since our response failed to satisfy the peer's challenge.  */
5385                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5386 
5387                 /* Determine if the application has registered a link down notification
5388                    callback.  */
5389                 if (ppp_ptr -> nx_ppp_link_down_callback)
5390                 {
5391 
5392                     /* Yes, call the application's callback function.  */
5393                     (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5394                 }
5395             }
5396 #ifndef NX_PPP_DISABLE_INFO
5397             else
5398             {
5399 
5400                 /* Increment the number of unhandled state machine events.   */
5401                 ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
5402             }
5403 #endif
5404             break;
5405         }
5406 
5407         case NX_PPP_CHAP_COMPLETED_STATE:
5408         {
5409 
5410             /* In this state the initial challenge(s) have been processed... This state is used to field
5411                additional challenges during the life of the link.  */
5412             if ((code == NX_PPP_CHAP_CHALLENGE_REQUEST) && (packet_ptr))
5413             {
5414 
5415                 /* Generate a challenge response and send it to the peer.  */
5416                 _nx_ppp_chap_challenge_respond(ppp_ptr, packet_ptr);
5417 
5418                 /* Stay in this state.  */
5419             }
5420             else if (code == NX_PPP_CHAP_CHALLENGE_FAILURE)
5421             {
5422 
5423                 /* Move to the failed state since our response failed to satisfy the peer's challenge.  */
5424                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5425 
5426                 /* Determine if the application has registered a link down notification
5427                    callback.  */
5428                 if (ppp_ptr -> nx_ppp_link_down_callback)
5429                 {
5430 
5431                     /* Yes, call the application's callback function.  */
5432                     (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5433                 }
5434             }
5435 #ifndef NX_PPP_DISABLE_INFO
5436             else
5437             {
5438 
5439                 /* Increment the number of unhandled state machine events.   */
5440                 ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
5441             }
5442 #endif
5443             break;
5444         }
5445 
5446         case NX_PPP_CHAP_COMPLETED_NEW_STATE:
5447         {
5448 
5449             /* In this state the new challenge(s) is issued... */
5450 
5451             /* Setup the retry counter.  */
5452             ppp_ptr -> nx_ppp_protocol_retry_counter =  0;
5453 
5454             /* Setup the timeout.  */
5455             ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
5456 
5457             /* Send challenge request to peer.  */
5458             _nx_ppp_chap_challenge_send (ppp_ptr);
5459 
5460             /* Move to the new challenge request sent state.  */
5461             ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_COMPLETED_NEW_SENT_STATE;
5462             break;
5463         }
5464 
5465         case NX_PPP_CHAP_COMPLETED_NEW_SENT_STATE:
5466         {
5467 
5468             /* In this state the initial challenge(s) have been processed... This state is used to field
5469                additional challenges during the life of the link.  */
5470             if ((code == NX_PPP_CHAP_CHALLENGE_REQUEST) && (packet_ptr))
5471             {
5472 
5473                 /* Generate a challenge response and send it to the peer.  */
5474                 _nx_ppp_chap_challenge_respond(ppp_ptr, packet_ptr);
5475 
5476                 /* Stay in this state.  */
5477             }
5478 
5479             else if (code == NX_PPP_CHAP_CHALLENGE_FAILURE)
5480             {
5481 
5482                 /* Determine if there is an application NAK callback.  */
5483                 if (ppp_ptr -> nx_ppp_nak_authentication_notify)
5484                 {
5485 
5486                     /* Yes, call the application's authentication NAK notify callback function.  */
5487                     (ppp_ptr -> nx_ppp_nak_authentication_notify)();
5488                 }
5489 
5490                 /* Move to the failed state since our response failed to satisfy the peer's challenge.  */
5491                 ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5492 
5493                 /* Mark the PPP instance as not authenticated.  */
5494                 ppp_ptr -> nx_ppp_authenticated =  NX_FALSE;
5495 
5496                 /* Determine if the application has registered a link down notification
5497                    callback.  */
5498                 if (ppp_ptr -> nx_ppp_link_down_callback)
5499                 {
5500 
5501                     /* Yes, call the application's callback function.  */
5502                     (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5503                 }
5504             }
5505 
5506             else if ((code == NX_PPP_CHAP_CHALLENGE_RESPONSE) && (packet_ptr))
5507             {
5508 
5509                 /* Determine if the challenge response is valid. Note this function all sends the Success or
5510                    Failure to the peer.  */
5511                 valid =  _nx_ppp_chap_challenge_validate(ppp_ptr, packet_ptr);
5512 
5513                 /* Is the login valid?  */
5514                 if (valid == NX_FALSE)
5515                 {
5516 
5517                     /* No: Determine if there is an application NAK callback.  */
5518                     if (ppp_ptr -> nx_ppp_nak_authentication_notify)
5519                     {
5520 
5521                         /* Yes, call the application's authentication NAK notify callback function.  */
5522                         (ppp_ptr -> nx_ppp_nak_authentication_notify)();
5523                     }
5524 
5525                     /* Enter into a failed state since challenge failed.  */
5526                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5527 
5528                     /* Mark the PPP instance as not authenticated.  */
5529                     ppp_ptr -> nx_ppp_authenticated =  NX_FALSE;
5530 
5531                     /* Determine if the application has registered a link down notification
5532                        callback.  */
5533                     if (ppp_ptr -> nx_ppp_link_down_callback)
5534                     {
5535 
5536                         /* Yes, call the application's callback function.  */
5537                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5538                     }
5539                 }
5540                 else
5541                 {
5542 
5543                     /* Simply move back to the completed state.  */
5544                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_COMPLETED_STATE;
5545 
5546                     /* Turn off the timeout.  */
5547                     ppp_ptr -> nx_ppp_timeout =  0;
5548                 }
5549             }
5550             /* Was a timeout received?  */
5551             else if (code == NX_PPP_CHAP_CHALLENGE_TIMEOUT)
5552             {
5553 
5554                 /* Increment the retry counter.  */
5555                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
5556 
5557                 /* Determine if the CHAP retry counter has been exceeded.  */
5558                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_CHAP_PROTOCOL_RETRIES)
5559                 {
5560 
5561                     /* Setup the timeout.  */
5562                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
5563 
5564                      /* Send challenge request to peer.  */
5565                     _nx_ppp_chap_challenge_send (ppp_ptr);
5566                 }
5567                 else
5568                 {
5569 
5570                     /* Retry counter exceeded.  */
5571 
5572                     /* Enter CHAP failed state.  PPP must be stopped and started to try again.  */
5573                     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_CHALLENGE_FAILED_STATE;
5574 
5575                     /* Determine if the application has registered a link down notification
5576                        callback.  */
5577                     if (ppp_ptr -> nx_ppp_link_down_callback)
5578                     {
5579 
5580                         /* Yes, call the application's callback function.  */
5581                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
5582                     }
5583                 }
5584             }
5585 #ifndef NX_PPP_DISABLE_INFO
5586             else
5587             {
5588 
5589                 /* Increment the number of unhandled state machine events.   */
5590                 ppp_ptr -> nx_ppp_chap_state_machine_unhandled_requests++;
5591             }
5592 #endif
5593             break;
5594         }
5595     }
5596 }
5597 
5598 
5599 /**************************************************************************/
5600 /*                                                                        */
5601 /*  FUNCTION                                               RELEASE        */
5602 /*                                                                        */
5603 /*    _nx_ppp_chap_challenge_send                         PORTABLE C      */
5604 /*                                                           6.1          */
5605 /*  AUTHOR                                                                */
5606 /*                                                                        */
5607 /*    Yuxin Zhou, Microsoft Corporation                                   */
5608 /*                                                                        */
5609 /*  DESCRIPTION                                                           */
5610 /*                                                                        */
5611 /*    This function sends a CHAP challenge to the peer.                   */
5612 /*                                                                        */
5613 /*  INPUT                                                                 */
5614 /*                                                                        */
5615 /*    ppp_ptr                               PPP instance pointer          */
5616 /*                                                                        */
5617 /*  OUTPUT                                                                */
5618 /*                                                                        */
5619 /*    None                                                                */
5620 /*                                                                        */
5621 /*  CALLS                                                                 */
5622 /*                                                                        */
5623 /*    nx_packet_allocate                    Allocate packet               */
5624 /*    (nx_ppp_chap_get_challenge_values)    Get values for challenge      */
5625 /*    _nx_ppp_packet_transmit               Send PAP response             */
5626 /*    _nx_utility_string_length_check       Check string length           */
5627 /*                                                                        */
5628 /*  CALLED BY                                                             */
5629 /*                                                                        */
5630 /*    _nx_ppp_chap_state_machine_update     Update CHAP state machine     */
5631 /*                                                                        */
5632 /*  RELEASE HISTORY                                                       */
5633 /*                                                                        */
5634 /*    DATE              NAME                      DESCRIPTION             */
5635 /*                                                                        */
5636 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5637 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5638 /*                                            resulting in version 6.1    */
5639 /*                                                                        */
5640 /**************************************************************************/
_nx_ppp_chap_challenge_send(NX_PPP * ppp_ptr)5641 void _nx_ppp_chap_challenge_send(NX_PPP *ppp_ptr)
5642 {
5643 
5644 UCHAR       id;
5645 UINT        length, length1, i, j;
5646 NX_PACKET   *packet_ptr;
5647 UINT        status;
5648 
5649 
5650     /* Determine if there is a challenge generation routine.  */
5651     if (ppp_ptr -> nx_ppp_chap_get_challenge_values)
5652     {
5653 
5654         /* Yes, get the challenge values.  */
5655         ppp_ptr -> nx_ppp_chap_get_challenge_values(ppp_ptr -> nx_ppp_chap_random_value,
5656                                                 (CHAR *) &id, ppp_ptr -> nx_ppp_chap_challenger_name);
5657     }
5658     else
5659     {
5660 
5661 #ifndef NX_PPP_DISABLE_INFO
5662 
5663         /* Increment the internal error counter.  */
5664         ppp_ptr -> nx_ppp_internal_errors++;
5665 #endif
5666 
5667         /* An error was detected, simply return.  */
5668         return;
5669     }
5670 
5671     /* Allocate a packet for the PPP CHAP challenge packet.  */
5672     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
5673 
5674     /* Determine if the packet was allocated successfully.  */
5675     if (status != NX_SUCCESS)
5676     {
5677 
5678 #ifndef NX_PPP_DISABLE_INFO
5679 
5680         /* Increment the number of packet allocation timeouts.  */
5681         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
5682 #endif
5683 
5684         /* An error was detected, simply return a NULL pointer.  */
5685         return;
5686     }
5687 
5688     /* Calculate the lengths of the challenger name and random value.  */
5689     if (_nx_utility_string_length_check(ppp_ptr -> nx_ppp_chap_challenger_name, &length1, NX_PPP_NAME_SIZE) ||
5690         _nx_utility_string_length_check(ppp_ptr -> nx_ppp_chap_random_value, &length, NX_PPP_VALUE_SIZE))
5691     {
5692 
5693         /* Release the packet.  */
5694         nx_packet_release(packet_ptr);
5695         return;
5696     }
5697 
5698     /* Check if out of boundary.  */
5699     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(length + 1 + length1 + 6))
5700     {
5701 
5702         /* Release the packet.  */
5703         nx_packet_release(packet_ptr);
5704         return;
5705     }
5706 
5707     /* Build CHAP challenge message.  */
5708     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
5709     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_CHAP_PROTOCOL & 0xFF;
5710     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_CHAP_CHALLENGE_REQUEST;
5711     packet_ptr -> nx_packet_prepend_ptr[3] =  id; /* ID */
5712 
5713     /* Setup the length.  */
5714     packet_ptr -> nx_packet_prepend_ptr[4] =  (UCHAR) ((((UINT) length) + 1 + ((UINT) length1) + 4) >> 8);
5715     packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR) ((((UINT) length) + 1 + ((UINT) length1) + 4) & 0xFF);
5716 
5717     /* Store the CHAP random value.  */
5718     packet_ptr -> nx_packet_prepend_ptr[6] =  (UCHAR)length;
5719     for (i = 0; i < length; i++)
5720     {
5721 
5722         /* Store byte of name.  */
5723         packet_ptr -> nx_packet_prepend_ptr[i+7] =  (UCHAR)(ppp_ptr -> nx_ppp_chap_random_value[i]);
5724     }
5725 
5726     /* Store CHAP challenge name.  */
5727     for (j = 0; j < length1; j++)
5728     {
5729 
5730         /* Store byte of name.  */
5731         packet_ptr -> nx_packet_prepend_ptr[j+i+7] =  (UCHAR)(ppp_ptr -> nx_ppp_chap_challenger_name[j]);
5732     }
5733 
5734     /* Setup the append pointer and the packet length.  */
5735     packet_ptr -> nx_packet_length =  ((UINT) length) + 1 + ((UINT) length1) + 4 + 2;
5736     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
5737 
5738 #ifndef NX_PPP_DISABLE_INFO
5739 
5740     /* Increment the number of CHAP frames sent.  */
5741     ppp_ptr -> nx_ppp_chap_frames_sent++;
5742 
5743     /* Increment the number of CHAP challenge requests.  */
5744     ppp_ptr -> nx_ppp_chap_challenge_requests_sent++;
5745 #endif
5746 
5747     /* Send challenge message.  */
5748     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
5749 }
5750 
5751 
5752 /**************************************************************************/
5753 /*                                                                        */
5754 /*  FUNCTION                                               RELEASE        */
5755 /*                                                                        */
5756 /*    _nx_ppp_chap_challenge_respond                      PORTABLE C      */
5757 /*                                                           6.1          */
5758 /*  AUTHOR                                                                */
5759 /*                                                                        */
5760 /*    Yuxin Zhou, Microsoft Corporation                                   */
5761 /*                                                                        */
5762 /*  DESCRIPTION                                                           */
5763 /*                                                                        */
5764 /*    This function processes the CHAP challenge request from the peer.   */
5765 /*                                                                        */
5766 /*  INPUT                                                                 */
5767 /*                                                                        */
5768 /*    ppp_ptr                               PPP instance pointer          */
5769 /*    packet_ptr                            Pointer to CHAP challenge     */
5770 /*                                                                        */
5771 /*  OUTPUT                                                                */
5772 /*                                                                        */
5773 /*    None                                                                */
5774 /*                                                                        */
5775 /*  CALLS                                                                 */
5776 /*                                                                        */
5777 /*    nx_packet_allocate                    Allocate packet               */
5778 /*    (nx_ppp_chap_get_responder_values)    Get responder values for reply*/
5779 /*    _nx_ppp_hash_generator                Generate MD5 hash             */
5780 /*    _nx_ppp_packet_transmit               Send PAP response             */
5781 /*                                                                        */
5782 /*  CALLED BY                                                             */
5783 /*                                                                        */
5784 /*    _nx_ppp_chap_state_machine_update     Update CHAP state machine     */
5785 /*                                                                        */
5786 /*  RELEASE HISTORY                                                       */
5787 /*                                                                        */
5788 /*    DATE              NAME                      DESCRIPTION             */
5789 /*                                                                        */
5790 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
5791 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
5792 /*                                            resulting in version 6.1    */
5793 /*                                                                        */
5794 /**************************************************************************/
_nx_ppp_chap_challenge_respond(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)5795 void _nx_ppp_chap_challenge_respond(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
5796 {
5797 
5798 UCHAR       name[NX_PPP_NAME_SIZE + 1], secret[NX_PPP_NAME_SIZE + 1];
5799 UCHAR       value[NX_PPP_VALUE_SIZE + 1], hvalue[NX_PPP_HASHED_VALUE_SIZE + 1];
5800 UCHAR       id;
5801 UINT        length, length1, i, j;
5802 NX_PACKET   *response_packet_ptr;
5803 UINT        status;
5804 UINT        name_length;
5805 
5806 
5807     /* Pickup the id and length.  */
5808     id =  packet_ptr -> nx_packet_prepend_ptr[3];
5809 
5810     /* Pickup the length.  */
5811     length =  (UINT) packet_ptr -> nx_packet_prepend_ptr[4];
5812     length1 = (UINT) packet_ptr -> nx_packet_prepend_ptr[5];
5813     length1 = (length << 8) | (length1) ;
5814 
5815     /* Check for valid packet length.  */
5816     if ((length1 + 2) > packet_ptr -> nx_packet_length)
5817     {
5818         return;
5819     }
5820 
5821     /* Pickup the length of the random value.  */
5822     length =  (UINT) packet_ptr -> nx_packet_prepend_ptr[6];
5823 
5824     /* Check for valid packet length.  */
5825     if ((length == 0) || ((ULONG)(length + 7) > packet_ptr -> nx_packet_length))
5826     {
5827         return;
5828     }
5829 
5830     /* Determine if the length is greater than the destination.  */
5831     name_length = length1 - length - 5;
5832     if ((length > NX_PPP_VALUE_SIZE) ||
5833         (name_length > NX_PPP_NAME_SIZE))
5834     {
5835 
5836 #ifndef NX_PPP_DISABLE_INFO
5837 
5838         /* Increment the number of internal errors.  */
5839         ppp_ptr -> nx_ppp_internal_errors++;
5840 #endif
5841         return;
5842     }
5843 
5844     /* Pickup the random value.  */
5845     for(i = 0; i < length; i++)
5846     {
5847 
5848         /* Pickup a byte of the random value.  */
5849         value[i] =  packet_ptr -> nx_packet_prepend_ptr[i+7];
5850     }
5851 
5852     /* Now pickup the challenge name.  */
5853     for(j = 0; j < name_length; j++)
5854     {
5855 
5856         /* Pickup a byte of the challenger name.  */
5857         name[j] =  packet_ptr -> nx_packet_prepend_ptr[i+j+7];
5858     }
5859 
5860     /* Null terminate it.  */
5861     name[j] =  0;
5862 
5863     /* Determine if there is a challenge get responder values routine.  */
5864     if (ppp_ptr -> nx_ppp_chap_get_responder_values)
5865     {
5866 
5867         /* Get name and password for this server   */
5868         ppp_ptr -> nx_ppp_chap_get_responder_values((CHAR*) name, (CHAR *) name, (CHAR *) secret);
5869     }
5870     else
5871     {
5872 
5873 #ifndef NX_PPP_DISABLE_INFO
5874 
5875         /* Increment the internal error counter.  */
5876         ppp_ptr -> nx_ppp_internal_errors++;
5877 #endif
5878 
5879         /* An error was detected, simply return a NULL pointer.  */
5880         return;
5881     }
5882 
5883     /* Generate hash value.  */
5884     _nx_ppp_hash_generator(hvalue, id, secret, value, length);
5885 
5886     /* Allocate a packet for the PPP CHAP response packet.  */
5887     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &response_packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
5888 
5889     /* Determine if the packet was allocated successfully.  */
5890     if (status != NX_SUCCESS)
5891     {
5892 
5893 #ifndef NX_PPP_DISABLE_INFO
5894 
5895         /* Increment the number of packet allocation timeouts.  */
5896         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
5897 #endif
5898 
5899         /* An error was detected, simply return a NULL pointer.  */
5900         return;
5901     }
5902 
5903     /* Calculate length of the name  */
5904     for(length = 0; name[length]; length++);
5905 
5906     /* Check if out of boundary.  */
5907     if ((UINT)(response_packet_ptr -> nx_packet_data_end - response_packet_ptr -> nx_packet_prepend_ptr) < (UINT)(length + NX_PPP_HASHED_VALUE_SIZE + 7))
5908     {
5909 
5910         /* Release the packet.  */
5911         nx_packet_release(packet_ptr);
5912         return;
5913     }
5914 
5915     /* Build CHAP challenge response message.  */
5916     response_packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
5917     response_packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_CHAP_PROTOCOL & 0xFF;
5918     response_packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_CHAP_CHALLENGE_RESPONSE;
5919     response_packet_ptr -> nx_packet_prepend_ptr[3] =  id; /* ID */
5920 
5921     /* Setup the length.  */
5922     response_packet_ptr -> nx_packet_prepend_ptr[4] =  (UCHAR) ((((UINT) length) + NX_PPP_HASHED_VALUE_SIZE + 5) >> 8);
5923     response_packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR) ((((UINT) length) + NX_PPP_HASHED_VALUE_SIZE + 5) & 0xFF);
5924 
5925     /* Set the length of the hashed response value.  */
5926     response_packet_ptr -> nx_packet_prepend_ptr[6] =  (UCHAR) NX_PPP_HASHED_VALUE_SIZE;
5927 
5928     /* Loop to insert the hashed value.  */
5929     for(i = 0; i < NX_PPP_HASHED_VALUE_SIZE; i++)
5930     {
5931 
5932         /* Copy one byte of the hashed value.  */
5933         response_packet_ptr -> nx_packet_prepend_ptr[i+7] =  hvalue[i];
5934     }
5935 
5936     /* Loop to insert the name.  */
5937     for(j = 0; j < length; j++)
5938     {
5939 
5940         /* Copy one byte of the name.  */
5941         response_packet_ptr -> nx_packet_prepend_ptr[i+j+7] =  name[j];
5942     }
5943 
5944     /* Setup the append pointer and the packet length.  */
5945     response_packet_ptr -> nx_packet_length =   length + NX_PPP_HASHED_VALUE_SIZE + 5 + 2;
5946     response_packet_ptr -> nx_packet_append_ptr =  response_packet_ptr -> nx_packet_prepend_ptr + response_packet_ptr -> nx_packet_length;
5947 
5948 #ifndef NX_PPP_DISABLE_INFO
5949 
5950     /* Increment the number of CHAP frames sent.  */
5951     ppp_ptr -> nx_ppp_chap_frames_sent++;
5952 
5953     /* Increment the number of CHAP responses sent.  */
5954     ppp_ptr -> nx_ppp_chap_challenge_responses_sent++;
5955 #endif
5956 
5957     /* Transmit response message.   */
5958     _nx_ppp_packet_transmit(ppp_ptr, response_packet_ptr);
5959 }
5960 
5961 
5962 /**************************************************************************/
5963 /*                                                                        */
5964 /*  FUNCTION                                               RELEASE        */
5965 /*                                                                        */
5966 /*    _nx_ppp_chap_challenge_validate                     PORTABLE C      */
5967 /*                                                           6.1          */
5968 /*  AUTHOR                                                                */
5969 /*                                                                        */
5970 /*    Yuxin Zhou, Microsoft Corporation                                   */
5971 /*                                                                        */
5972 /*  DESCRIPTION                                                           */
5973 /*                                                                        */
5974 /*    This function validates the CHAP response from the peer.            */
5975 /*                                                                        */
5976 /*  INPUT                                                                 */
5977 /*                                                                        */
5978 /*    ppp_ptr                               PPP instance pointer          */
5979 /*    packet_ptr                            Pointer to CHAP challenge     */
5980 /*                                                                        */
5981 /*  OUTPUT                                                                */
5982 /*                                                                        */
5983 /*    status                                NX_TRUE - valid login         */
5984 /*                                          NX_FALSE - invalid login      */
5985 /*                                                                        */
5986 /*  CALLS                                                                 */
5987 /*                                                                        */
5988 /*    nx_packet_allocate                    Allocate packet               */
5989 /*    (nx_ppp_chap_get_verification_values) Get verification values       */
5990 /*    _nx_ppp_hash_generator                Generate MD5 hash             */
5991 /*    _nx_ppp_packet_transmit               Send PAP response             */
5992 /*                                                                        */
5993 /*  CALLED BY                                                             */
5994 /*                                                                        */
5995 /*    _nx_ppp_chap_state_machine_update     Update CHAP state machine     */
5996 /*                                                                        */
5997 /*  RELEASE HISTORY                                                       */
5998 /*                                                                        */
5999 /*    DATE              NAME                      DESCRIPTION             */
6000 /*                                                                        */
6001 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6002 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6003 /*                                            resulting in version 6.1    */
6004 /*                                                                        */
6005 /**************************************************************************/
_nx_ppp_chap_challenge_validate(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)6006 UINT  _nx_ppp_chap_challenge_validate(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
6007 {
6008 
6009 UCHAR       name[NX_PPP_NAME_SIZE + 1], secret[NX_PPP_NAME_SIZE + 1];
6010 UCHAR       hvalue[NX_PPP_HASHED_VALUE_SIZE + 1];
6011 UCHAR       hvalue1[NX_PPP_HASHED_VALUE_SIZE + 1];
6012 UCHAR       id;
6013 UINT        length, length1, i, j;
6014 NX_PACKET   *response_packet_ptr;
6015 UINT        status;
6016 UINT        name_length;
6017 
6018 
6019     /* Pickup the id and length.  */
6020     id =  packet_ptr -> nx_packet_prepend_ptr[3];
6021 
6022     /* Pickup the length.  */
6023     length =  (UINT) packet_ptr -> nx_packet_prepend_ptr[4];
6024     length1 = (UINT) packet_ptr -> nx_packet_prepend_ptr[5];
6025     length1 = (length << 8) | (length1) ;
6026 
6027     /* Check for valid packet length.  */
6028     if ((length1 + 2) > packet_ptr -> nx_packet_length)
6029     {
6030         return(NX_FALSE);
6031     }
6032 
6033     /* Pickup the length of the hashed value.  */
6034     length =  (UINT) packet_ptr -> nx_packet_prepend_ptr[6];
6035 
6036     /* Check for valid packet length.  */
6037     if ((length == 0) || ((ULONG)(length + 7) > packet_ptr -> nx_packet_length))
6038     {
6039         return(NX_FALSE);
6040     }
6041 
6042     /* Determine if the length is greater than the destination.  */
6043     name_length = length1 - length - 5;
6044     if ((length > NX_PPP_HASHED_VALUE_SIZE) ||
6045         (name_length > NX_PPP_NAME_SIZE))
6046     {
6047 
6048 #ifndef NX_PPP_DISABLE_INFO
6049 
6050         /* Increment the number of internal errors.  */
6051         ppp_ptr -> nx_ppp_internal_errors++;
6052 #endif
6053 
6054         /* Return false in case of internal error.  */
6055         return(NX_FALSE);
6056     }
6057 
6058     /* Pickup the hashed value.  */
6059     for(i = 0; i < length; i++)
6060     {
6061 
6062         /* Pickup one byte of the hashed value.  */
6063         hvalue[i] =  packet_ptr -> nx_packet_prepend_ptr[i+7];
6064     }
6065 
6066     /* Pickup the name.  */
6067     for(j = 0; j < name_length; j++)
6068     {
6069 
6070         /* Pickup one byte of the hashed value.  */
6071         name[j] =  packet_ptr -> nx_packet_prepend_ptr[i+j+7];
6072     }
6073 
6074     /* Null terminate the name.  */
6075     name[j] = 0;
6076 
6077     /* Determine if there is a challenge get verification values routine.  */
6078     if (ppp_ptr -> nx_ppp_chap_get_verification_values)
6079     {
6080 
6081         /* Get name and password for this server   */
6082         ppp_ptr -> nx_ppp_chap_get_verification_values(ppp_ptr -> nx_ppp_chap_challenger_name, (CHAR *) name, (CHAR *) secret);
6083     }
6084     else
6085     {
6086 
6087 #ifndef NX_PPP_DISABLE_INFO
6088 
6089         /* Increment the internal error counter.  */
6090         ppp_ptr -> nx_ppp_internal_errors++;
6091 #endif
6092 
6093         /* Return false in case of internal error.  */
6094         return(NX_FALSE);
6095     }
6096 
6097     /* Generate hash value.  */
6098     _nx_ppp_hash_generator(hvalue1, id, secret, (UCHAR *) ppp_ptr -> nx_ppp_chap_random_value, 0);
6099 
6100     /* Compare the computed hash value with the hash value received.  */
6101     for(i = 0; i < NX_PPP_HASHED_VALUE_SIZE; i++)
6102     {
6103 
6104         /* Are the hash values equal?  */
6105         if (hvalue[i] != hvalue1[i])
6106         {
6107             /* No, get out of the loop.  */
6108             break;
6109         }
6110     }
6111 
6112 
6113     /* Allocate a packet for the PPP CHAP response packet.  */
6114     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &response_packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
6115 
6116     /* Determine if the packet was allocated successfully.  */
6117     if (status != NX_SUCCESS)
6118     {
6119 
6120 #ifndef NX_PPP_DISABLE_INFO
6121 
6122         /* Increment the number of packet allocation timeouts.  */
6123         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
6124 #endif
6125 
6126         /* Return false in case of internal error.  */
6127         return(NX_FALSE);
6128     }
6129 
6130     /* Determine if challenge was successful.  */
6131     if (i == NX_PPP_HASHED_VALUE_SIZE)
6132     {
6133 
6134         /* Build CHAP ACK message.  */
6135         response_packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
6136         response_packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_CHAP_PROTOCOL & 0xFF;
6137         response_packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_CHAP_CHALLENGE_SUCCESS;
6138         response_packet_ptr -> nx_packet_prepend_ptr[3] =  id; /* ID */
6139 
6140         /* Setup the length.  */
6141         response_packet_ptr -> nx_packet_prepend_ptr[4] =  (UCHAR) 0;
6142         response_packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR) 4;
6143 
6144         /* Setup the append pointer and the packet length.  */
6145         response_packet_ptr -> nx_packet_length = 6;
6146         response_packet_ptr -> nx_packet_append_ptr =  response_packet_ptr -> nx_packet_prepend_ptr + response_packet_ptr -> nx_packet_length;
6147 
6148 #ifndef NX_PPP_DISABLE_INFO
6149 
6150         /* Increment the number of CHAP frames sent.  */
6151         ppp_ptr -> nx_ppp_chap_frames_sent++;
6152 
6153         /* Increment the number of CHAP success notifications sent.  */
6154         ppp_ptr -> nx_ppp_chap_challenge_successes_sent++;
6155 #endif
6156 
6157         /* Transmit the message.  */
6158         _nx_ppp_packet_transmit(ppp_ptr, response_packet_ptr);
6159 
6160         /* Return true to indicate the response was valid.  */
6161         return(NX_TRUE);
6162     }
6163     else
6164     {
6165 
6166         /* Build CHAP NAK message.  */
6167         response_packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_CHAP_PROTOCOL & 0xFF00) >> 8;
6168         response_packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_CHAP_PROTOCOL & 0xFF;
6169         response_packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_CHAP_CHALLENGE_FAILURE;
6170         response_packet_ptr -> nx_packet_prepend_ptr[3] =  id; /* ID */
6171 
6172         /* Setup the length.  */
6173         response_packet_ptr -> nx_packet_prepend_ptr[4] =  (UCHAR) 0;
6174         response_packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR) 4;
6175 
6176         /* Setup the append pointer and the packet length.  */
6177         response_packet_ptr -> nx_packet_length = 6;
6178         response_packet_ptr -> nx_packet_append_ptr =  response_packet_ptr -> nx_packet_prepend_ptr + response_packet_ptr -> nx_packet_length;
6179 
6180 #ifndef NX_PPP_DISABLE_INFO
6181 
6182         /* Increment the number of CHAP frames sent.  */
6183         ppp_ptr -> nx_ppp_chap_frames_sent++;
6184 
6185         /* Increment the number of CHAP failure notifications sent.  */
6186         ppp_ptr -> nx_ppp_chap_challenge_failures_sent++;
6187 #endif
6188 
6189         /* Transmit the message.  */
6190         _nx_ppp_packet_transmit(ppp_ptr, response_packet_ptr);
6191 
6192         /* Return false to indicate the response was invalid.  */
6193         return(NX_FALSE);
6194     }
6195 }
6196 #endif
6197 
6198 
6199 /**************************************************************************/
6200 /*                                                                        */
6201 /*  FUNCTION                                               RELEASE        */
6202 /*                                                                        */
6203 /*    _nx_ppp_ipcp_state_machine_update                   PORTABLE C      */
6204 /*                                                           6.1.2        */
6205 /*  AUTHOR                                                                */
6206 /*                                                                        */
6207 /*    Yuxin Zhou, Microsoft Corporation                                   */
6208 /*                                                                        */
6209 /*  DESCRIPTION                                                           */
6210 /*                                                                        */
6211 /*    This function processes events and state changes in the PPP IPCP    */
6212 /*    state machine.                                                      */
6213 /*                                                                        */
6214 /*  INPUT                                                                 */
6215 /*                                                                        */
6216 /*    ppp_ptr                               PPP instance pointer          */
6217 /*    packet_ptr                            Packet pointer                */
6218 /*                                                                        */
6219 /*  OUTPUT                                                                */
6220 /*                                                                        */
6221 /*    None                                                                */
6222 /*                                                                        */
6223 /*  CALLS                                                                 */
6224 /*                                                                        */
6225 /*    _nx_ppp_ipcp_configure_check          Check configuration info      */
6226 /*    _nx_ppp_ipcp_configure_request_send   Send configuration request    */
6227 /*    _nx_ppp_ipcp_response_extract         Extract info from response    */
6228 /*    _nx_ppp_ipcp_response_send            Send response                 */
6229 /*    _nx_ppp_ipcp_terminate_send           Send terminate                */
6230 /*    _nx_ppp_ipcp_terminate_ack_send       Send terminate ack            */
6231 /*    nx_ip_interface_address_set           Set interface IP address      */
6232 /*                                                                        */
6233 /*  CALLED BY                                                             */
6234 /*                                                                        */
6235 /*    _nx_ppp_receive_packet_process        Receive PPP packet processing */
6236 /*    _nx_ppp_timeout                       PPP timeout                   */
6237 /*                                                                        */
6238 /*  RELEASE HISTORY                                                       */
6239 /*                                                                        */
6240 /*    DATE              NAME                      DESCRIPTION             */
6241 /*                                                                        */
6242 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6243 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6244 /*                                            resulting in version 6.1    */
6245 /*  11-09-2020     Yuxin Zhou               Modified comment(s),          */
6246 /*                                            corrected the NAKed list    */
6247 /*                                            pointer,                    */
6248 /*                                            resulting in version 6.1.2  */
6249 /*                                                                        */
6250 /**************************************************************************/
_nx_ppp_ipcp_state_machine_update(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)6251 void _nx_ppp_ipcp_state_machine_update(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
6252 {
6253 
6254 UINT    acceptable_configuration;
6255 UCHAR   good_data[NX_PPP_OPTION_MESSAGE_LENGTH];
6256 UCHAR   code;
6257 
6258 
6259     /* Determine if a packet is present. If so, derive the event from the packet.  */
6260     if (packet_ptr)
6261     {
6262 
6263 #ifndef NX_PPP_DISABLE_INFO
6264 
6265         /* Increment the number of IPCP frames received.  */
6266         ppp_ptr -> nx_ppp_ipcp_frames_received++;
6267 #endif
6268 
6269         /* Pickup the type of received IPCP code.  */
6270         code =  packet_ptr -> nx_packet_prepend_ptr[2];
6271 
6272         /* Remember receive id.  */
6273         ppp_ptr -> nx_ppp_receive_id =  packet_ptr -> nx_packet_prepend_ptr[3];
6274 
6275         /* Is the code supported by PPP?  */
6276         if ((code < NX_PPP_IPCP_CONFIGURE_REQUEST) ||
6277             (code > NX_PPP_IPCP_TERMINATE_ACK))
6278         {
6279 
6280 #ifndef NX_PPP_DISABLE_INFO
6281 
6282             /* Increment the number of internal errors.  */
6283             ppp_ptr -> nx_ppp_internal_errors++;
6284 
6285             /* Increment the number of unhandled requests.  */
6286             ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
6287 #endif
6288             return;
6289         }
6290     }
6291     else
6292     {
6293 
6294         /* Set the code to timeout to indicate a timeout has occurred.  */
6295         code =  NX_PPP_IPCP_TIMEOUT;
6296     }
6297 
6298 #ifndef NX_PPP_DISABLE_INFO
6299 
6300     /* Increment the corresponding request counter.  */
6301     switch (code)
6302     {
6303 
6304     case NX_PPP_IPCP_CONFIGURE_REQUEST:
6305 
6306         /* Increment the number of IPCP configure requests received.  */
6307         ppp_ptr -> nx_ppp_ipcp_configure_requests_received++;
6308         break;
6309 
6310     case NX_PPP_IPCP_CONFIGURE_ACK:
6311 
6312         /* Increment the number of IPCP configure ACKs received.  */
6313         ppp_ptr -> nx_ppp_ipcp_configure_acks_received++;
6314         break;
6315 
6316     case NX_PPP_IPCP_CONFIGURE_NAK:
6317 
6318         /* Increment the number of IPCP configure NAKs received.  */
6319         ppp_ptr -> nx_ppp_ipcp_configure_naks_received++;
6320         break;
6321 
6322     case NX_PPP_IPCP_CONFIGURE_REJECT:
6323 
6324         /* Increment the number of IPCP configure rejects received.  */
6325         ppp_ptr -> nx_ppp_ipcp_configure_rejects_received++;
6326         break;
6327 
6328     case NX_PPP_IPCP_TERMINATE_REQUEST:
6329 
6330         /* Increment the number of IPCP terminate requests received.  */
6331         ppp_ptr -> nx_ppp_ipcp_terminate_requests_received++;
6332         break;
6333 
6334     case NX_PPP_IPCP_TERMINATE_ACK:
6335 
6336         /* Increment the number of IPCP terminate ACKs received.  */
6337         ppp_ptr -> nx_ppp_ipcp_terminate_acks_received++;
6338         break;
6339 
6340     case NX_PPP_IPCP_TIMEOUT:
6341 
6342         /* Determine if we are in the initial state. If so, this really isn't a timeout.  */
6343         if (ppp_ptr -> nx_ppp_ipcp_state != NX_PPP_IPCP_START_STATE)
6344         {
6345 
6346             /* Increment the number of IPCP state machine timeouts.  */
6347             ppp_ptr -> nx_ppp_ipcp_state_machine_timeouts++;
6348         }
6349         break;
6350     }
6351 #endif
6352 
6353     /* Process relative to the current state.  */
6354     switch (ppp_ptr -> nx_ppp_ipcp_state)
6355     {
6356 
6357         case NX_PPP_IPCP_START_STATE:
6358         {
6359 
6360             /* Initial IPCP state.  */
6361 
6362             /* Initialize the NAK and rejected list.  */
6363 #ifndef NX_PPP_DNS_OPTION_DISABLE
6364             ppp_ptr -> nx_ppp_naked_list[0] =       0;
6365             ppp_ptr -> nx_ppp_naked_list[1] =       0;
6366 #else
6367             ppp_ptr -> nx_ppp_naked_list[0] =       1;
6368             ppp_ptr -> nx_ppp_naked_list[1] =       1;
6369 #endif
6370 
6371             ppp_ptr -> nx_ppp_peer_naked_list[0] =  0;
6372             ppp_ptr -> nx_ppp_rejected_list[0] =    0;
6373 
6374             /* Setup the retry counter.  */
6375             ppp_ptr -> nx_ppp_protocol_retry_counter =  0;
6376 
6377             /* Setup the timeout.  */
6378             ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
6379 
6380             /* Send the configuration request.  */
6381             _nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
6382 
6383             /* Move into the request sent state.  */
6384             ppp_ptr -> nx_ppp_ipcp_state = NX_PPP_IPCP_CONFIGURE_REQUEST_SENT_STATE;
6385             break;
6386         }
6387 
6388         case NX_PPP_IPCP_CONFIGURE_REQUEST_SENT_STATE:
6389         {
6390 
6391             /* In this state, we have sent a configuration request but had not received an ACK
6392                or a configuration request from the peer.  */
6393 
6394             /* Process relative to the incoming code.  */
6395             if (code ==  NX_PPP_IPCP_CONFIGURE_ACK)
6396             {
6397 
6398                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
6399                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
6400                 {
6401 
6402 #ifndef NX_PPP_DISABLE_INFO
6403 
6404                     /* Increment the invalid frame ID counter.  */
6405                     ppp_ptr -> nx_ppp_invalid_frame_id++;
6406 #endif
6407 
6408                     /* Discard this request by simply returning!  */
6409                     return;
6410                 }
6411 
6412                 /* The peer has ACKed our configuration request. Move to the
6413                    configure request ACKed state.  */
6414                 ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE;
6415 
6416                 /* Turn off the timeout for the configuration request.  */
6417                 ppp_ptr -> nx_ppp_timeout =  0;
6418             }
6419 
6420             else if (code == NX_PPP_IPCP_CONFIGURE_REJECT)
6421             {
6422 
6423                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
6424                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
6425                 {
6426 
6427 #ifndef NX_PPP_DISABLE_INFO
6428 
6429                     /* Increment the invalid frame ID counter.  */
6430                     ppp_ptr -> nx_ppp_invalid_frame_id++;
6431 #endif
6432 
6433                     /* Discard this request by simply returning!  */
6434                     return;
6435                 }
6436 
6437                 /* Set the NAK option list, just to indicate to the configure request that
6438                    the IPCP request without DNS option is what we want.  */
6439                 ppp_ptr -> nx_ppp_naked_list[0] =  1;
6440 
6441                 /* Send the configuration request.  */
6442                 _nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
6443             }
6444 
6445             else if ((code ==  NX_PPP_IPCP_CONFIGURE_NAK) && (packet_ptr))
6446             {
6447 
6448                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
6449                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
6450                 {
6451 
6452 #ifndef NX_PPP_DISABLE_INFO
6453 
6454                     /* Increment the invalid frame ID counter.  */
6455                     ppp_ptr -> nx_ppp_invalid_frame_id++;
6456 #endif
6457 
6458                     /* Discard this request by simply returning!  */
6459                     return;
6460                 }
6461 
6462                 /* Extract the information from response... looking for IP address and possibly DNS server IP address.  */
6463                 _nx_ppp_ipcp_response_extract(ppp_ptr, packet_ptr);
6464 
6465                 /* Send the configuration request.  */
6466                 _nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
6467             }
6468 
6469             else if ((code == NX_PPP_IPCP_CONFIGURE_REQUEST) && (packet_ptr))
6470             {
6471 
6472                 /* The peer has sent a configuration request.  */
6473 
6474                 /* Check configuration information.  */
6475                 acceptable_configuration =  _nx_ppp_ipcp_configure_check(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list,
6476                                                                          ppp_ptr -> nx_ppp_rejected_list,
6477                                                                          good_data);
6478 
6479                 /* Check for acceptable configuration.  */
6480                 if (acceptable_configuration == NX_TRUE)
6481                 {
6482 
6483                     /* Yes, send an ack.  */
6484                     _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_ACK, good_data, good_data[1], packet_ptr);
6485 
6486                     /* Move to the state where the peer's configuration has been ACKed.  */
6487                     ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_PEER_CONFIGURE_REQUEST_ACKED_STATE;
6488                 }
6489                 else
6490                 {
6491 
6492                     /* Otherwise, configuration is unacceptable, send a nak.  */
6493 
6494                     /* Check rejected list.  */
6495                     if (ppp_ptr -> nx_ppp_rejected_list[0] != 0)
6496                     {
6497 
6498                         /* Yes, there are rejected options so send a configure reject.  */
6499                         _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_REJECT,
6500                                                    &ppp_ptr -> nx_ppp_rejected_list[1],
6501                                                    ppp_ptr -> nx_ppp_rejected_list[0], NX_NULL);
6502 
6503                     }
6504                     else if (ppp_ptr -> nx_ppp_peer_naked_list[0] != 0)
6505                     {
6506 
6507                         /* Yes, there are naked options so send a new request.  */
6508                         _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_NAK,
6509                                                    &ppp_ptr -> nx_ppp_peer_naked_list[1],
6510                                                    ppp_ptr -> nx_ppp_peer_naked_list[0], NX_NULL);
6511 
6512                     }
6513                 }
6514             }
6515             else if (code == NX_PPP_IPCP_TIMEOUT)
6516             {
6517 
6518                 /* Increment the retry counter.  */
6519                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
6520 
6521                 /* Determine if the IPCP retry counter has been exceeded.  */
6522                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_IPCP_PROTOCOL_RETRIES)
6523                 {
6524 
6525                     /* Setup the timeout.  */
6526                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
6527 
6528                     /* Timeout, send the configuration request.  */
6529                     _nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
6530                 }
6531                 else
6532                 {
6533 
6534                     /* Retry counter exceeded.  */
6535 
6536                     /* Enter IPCP failed state.  PPP must be stopped and started to try again.  */
6537                     ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_FAILED_STATE;
6538 
6539                     /* Determine if the application has registered a link down notification
6540                        callback.  */
6541                     if (ppp_ptr -> nx_ppp_link_down_callback)
6542                     {
6543 
6544                         /* Yes, call the application's callback function.  */
6545                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
6546                     }
6547                 }
6548             }
6549 #ifndef NX_PPP_DISABLE_INFO
6550             else
6551             {
6552 
6553                 /* Increment the number of unhandled state machine events.   */
6554                 ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
6555             }
6556 #endif
6557             break;
6558         }
6559 
6560         case NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE:
6561         {
6562 
6563             /* In this state, we have received the ACK for our configuration request, but have not yet
6564                received a configuration request from the peer.  */
6565 
6566             /* Process relative to the incoming code.  */
6567             if ((code == NX_PPP_IPCP_CONFIGURE_REQUEST) && (packet_ptr))
6568             {
6569 
6570                 /* The peer has sent a configuration request.  */
6571 
6572                 /* Check configuration information.  */
6573                 acceptable_configuration =  _nx_ppp_ipcp_configure_check(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, good_data);
6574 
6575                 /* Check for acceptable configuration.  */
6576                 if (acceptable_configuration == NX_TRUE)
6577                 {
6578 
6579                     /* Yes, send an ack.  */
6580                     _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_ACK, good_data, good_data[1], packet_ptr);
6581 
6582                     /* Move to the state where the peer's configuration has been ACKed.  */
6583                     ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_COMPLETED_STATE;
6584 
6585                     /* Set the IP address for the specific interface from the configuration.   */
6586                     nx_ip_interface_address_set(ppp_ptr -> nx_ppp_ip_ptr, ppp_ptr -> nx_ppp_interface_index,
6587                                                 IP_ADDRESS(ppp_ptr -> nx_ppp_ipcp_local_ip[0],
6588                                                            ppp_ptr -> nx_ppp_ipcp_local_ip[1],
6589                                                            ppp_ptr -> nx_ppp_ipcp_local_ip[2],
6590                                                            ppp_ptr -> nx_ppp_ipcp_local_ip[3]),
6591                                                            0xffffffff);
6592 
6593                     /* Set gateway address.  */
6594                     (ppp_ptr -> nx_ppp_ip_ptr) -> nx_ip_gateway_address =   (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_address;
6595                     (ppp_ptr -> nx_ppp_ip_ptr) -> nx_ip_gateway_interface =  ppp_ptr -> nx_ppp_interface_ptr;
6596 
6597                     /* Turn off the timeout.  */
6598                     ppp_ptr -> nx_ppp_timeout =  0;
6599                 }
6600                 else
6601                 {
6602 
6603                     /* Otherwise, configuration is unacceptable, send a NAK.  */
6604 
6605                     /* Check rejected list.  */
6606                     if (ppp_ptr -> nx_ppp_rejected_list[0] != 0)
6607                     {
6608 
6609                         /* Yes, there are rejected options so send a new request.  */
6610                         _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_REJECT, &ppp_ptr -> nx_ppp_rejected_list[1], ppp_ptr -> nx_ppp_rejected_list[0], NX_NULL);
6611                     }
6612                     else if (ppp_ptr -> nx_ppp_peer_naked_list[0] != 0)
6613                     {
6614 
6615                         /* Yes, there are naked options so send a new request.  */
6616                         _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_NAK, &ppp_ptr -> nx_ppp_peer_naked_list[1], ppp_ptr -> nx_ppp_peer_naked_list[0], NX_NULL);
6617                     }
6618                 }
6619             }
6620 #ifndef NX_PPP_DISABLE_INFO
6621             else
6622             {
6623 
6624                 /* Increment the number of unhandled state machine events.   */
6625                 ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
6626             }
6627 #endif
6628             break;
6629         }
6630 
6631         case NX_PPP_IPCP_PEER_CONFIGURE_REQUEST_ACKED_STATE:
6632         {
6633 
6634             /* In this state, we have sent our configuration request, but haven't received an ACK. We have also received
6635                a peer configuration request and have ACKed that request.  */
6636 
6637             /* Process relative to the incoming code.  */
6638             if (code ==  NX_PPP_IPCP_CONFIGURE_ACK)
6639             {
6640 
6641                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
6642                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
6643                 {
6644 
6645 #ifndef NX_PPP_DISABLE_INFO
6646 
6647                     /* Increment the invalid frame ID counter.  */
6648                     ppp_ptr -> nx_ppp_invalid_frame_id++;
6649 #endif
6650 
6651                     /* Discard this request by simply returning!  */
6652                     return;
6653                 }
6654 
6655                 /* The peer has ACKed our configuration request. Move to the
6656                    IPCP completed state.  */
6657                 ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_COMPLETED_STATE;
6658 
6659                 /* Turn off the timeout for the configuration request.  */
6660                 ppp_ptr -> nx_ppp_timeout =  0;
6661 
6662                 /* Set the IP address for the specific interface from the configuration.   */
6663                 nx_ip_interface_address_set(ppp_ptr -> nx_ppp_ip_ptr, ppp_ptr -> nx_ppp_interface_index,
6664                                             IP_ADDRESS(ppp_ptr -> nx_ppp_ipcp_local_ip[0], ppp_ptr -> nx_ppp_ipcp_local_ip[1],
6665                                                        ppp_ptr -> nx_ppp_ipcp_local_ip[2], ppp_ptr -> nx_ppp_ipcp_local_ip[3]),
6666                                                        0xffffffff);
6667 
6668                 /* Set gateway address.  */
6669                 (ppp_ptr -> nx_ppp_ip_ptr) -> nx_ip_gateway_address =    (ppp_ptr -> nx_ppp_interface_ptr) -> nx_interface_ip_address;
6670                 (ppp_ptr -> nx_ppp_ip_ptr) -> nx_ip_gateway_interface =  ppp_ptr -> nx_ppp_interface_ptr;
6671 
6672                 /* Turn off the timeout.  */
6673                 ppp_ptr -> nx_ppp_timeout =  0;
6674             }
6675 
6676             else if (code == NX_PPP_IPCP_CONFIGURE_REJECT)
6677             {
6678 
6679                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
6680                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
6681                 {
6682 
6683 #ifndef NX_PPP_DISABLE_INFO
6684 
6685                     /* Increment the invalid frame ID counter.  */
6686                     ppp_ptr -> nx_ppp_invalid_frame_id++;
6687 #endif
6688 
6689                     /* Discard this request by simply returning!  */
6690                     return;
6691                 }
6692 
6693                 /* Set the NAK option list, just to indicate to the configure request that
6694                    the IPCP request without DNS option is what we want.  */
6695                 ppp_ptr -> nx_ppp_naked_list[0] =  1;
6696 
6697                 /* Send the configuration request.  */
6698                 _nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
6699             }
6700 
6701             else if ((code ==  NX_PPP_IPCP_CONFIGURE_NAK) && (packet_ptr))
6702             {
6703 
6704                 /* Determine if the ID matches our last transmit ID. If not, just discard it.  */
6705                 if (ppp_ptr -> nx_ppp_transmit_id != ppp_ptr -> nx_ppp_receive_id)
6706                 {
6707 
6708 #ifndef NX_PPP_DISABLE_INFO
6709 
6710                     /* Increment the invalid frame ID counter.  */
6711                     ppp_ptr -> nx_ppp_invalid_frame_id++;
6712 #endif
6713 
6714                     /* Discard this request by simply returning!  */
6715                     return;
6716                 }
6717 
6718                 /* Extract the information from response... looking for IP address and possibly DNS server IP address.  */
6719                 _nx_ppp_ipcp_response_extract(ppp_ptr, packet_ptr);
6720 
6721                 /* Send the configuration request.  */
6722                 _nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
6723             }
6724 
6725             else if (code == NX_PPP_IPCP_TIMEOUT)
6726             {
6727 
6728                 /* Increment the retry counter.  */
6729                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
6730 
6731                 /* Setup the timeout.  */
6732                 ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
6733 
6734                 /* Timeout, send the configuration request.  */
6735                 _nx_ppp_ipcp_configure_request_send(ppp_ptr, ppp_ptr -> nx_ppp_naked_list);
6736             }
6737 
6738 #ifndef NX_PPP_DISABLE_INFO
6739             else
6740             {
6741 
6742                 /* Increment the number of unhandled state machine events.   */
6743                 ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
6744             }
6745 #endif
6746             break;
6747         }
6748 
6749         case NX_PPP_IPCP_COMPLETED_STATE:
6750         {
6751 
6752             /* IPCP is up and operational at this point.  */
6753 
6754             /* Process relative to incoming code.  */
6755             if (code == NX_PPP_IPCP_TERMINATE_REQUEST)
6756             {
6757 
6758                 /* Increment the retry counter.  */
6759                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
6760 
6761                 /* Setup the timeout.  */
6762                 ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
6763 
6764                 /* ACK the terminate request.  */
6765                 _nx_ppp_ipcp_terminate_ack_send(ppp_ptr);
6766 
6767                 /* Send terminate request.  */
6768                 _nx_ppp_ipcp_terminate_send(ppp_ptr);
6769 
6770                 /* Move into the IPCP stopping state.  */
6771                 ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_STOPPING_STATE;
6772             }
6773             else if ((code == NX_PPP_IPCP_CONFIGURE_REQUEST) && (packet_ptr))
6774             {
6775                 /* The peer has sent a configuration request.  */
6776 
6777                 /* Check configuration information.  */
6778                 acceptable_configuration =  _nx_ppp_ipcp_configure_check(ppp_ptr, packet_ptr, ppp_ptr -> nx_ppp_peer_naked_list, ppp_ptr -> nx_ppp_rejected_list, good_data);
6779 
6780                 /* Check for acceptable configuration.  */
6781                 if (acceptable_configuration == NX_TRUE)
6782                 {
6783 
6784                     /* Yes, send an ack.  */
6785                     _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_ACK, good_data, good_data[1], packet_ptr);
6786                 }
6787                 else
6788                 {
6789                     /* Otherwise, configuration is unacceptable, send a nak.  */
6790 
6791                     /* Check rejected list.  */
6792                     if (ppp_ptr -> nx_ppp_rejected_list[0] != 0)
6793                     {
6794 
6795                         /* Yes, there are rejected options so send a new request.  */
6796                         _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_REJECT, &ppp_ptr -> nx_ppp_rejected_list[1], ppp_ptr -> nx_ppp_rejected_list[0], NX_NULL);
6797                     }
6798                     else if (ppp_ptr -> nx_ppp_peer_naked_list[0] != 0)
6799                     {
6800 
6801                         /* Yes, there are naked options so send a new request.  */
6802                         _nx_ppp_ipcp_response_send(ppp_ptr, NX_PPP_IPCP_CONFIGURE_NAK, &ppp_ptr -> nx_ppp_peer_naked_list[1], ppp_ptr -> nx_ppp_peer_naked_list[0], NX_NULL);
6803                     }
6804                 }
6805             }
6806 
6807 #ifndef NX_PPP_DISABLE_INFO
6808             else
6809             {
6810 
6811                 /* Increment the number of unhandled state machine events.   */
6812                 ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
6813             }
6814 #endif
6815             break;
6816         }
6817 
6818         case NX_PPP_LCP_STOPPING_STATE:
6819         {
6820 
6821             /* We received a terminate request from the other side and just need to get the ACK.  */
6822 
6823             /* Process relative to incoming code.  */
6824             if (code == NX_PPP_IPCP_TERMINATE_ACK)
6825             {
6826 
6827                 /* Move the the stopped state.  */
6828                 ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_STOPPED_STATE;
6829             }
6830             else if (code == NX_PPP_IPCP_TIMEOUT)
6831             {
6832 
6833                 /* Increment the retry counter.  */
6834                 ppp_ptr -> nx_ppp_protocol_retry_counter++;
6835 
6836                 /* Determine if the IPCP retry counter has been exceeded.  */
6837                 if (ppp_ptr -> nx_ppp_protocol_retry_counter < NX_PPP_MAX_IPCP_PROTOCOL_RETRIES)
6838                 {
6839 
6840                     /* Setup the timeout.  */
6841                     ppp_ptr -> nx_ppp_timeout =  NX_PPP_PROTOCOL_TIMEOUT;
6842 
6843                     /* Send terminate request.  */
6844                     _nx_ppp_ipcp_terminate_send(ppp_ptr);
6845                 }
6846                 else
6847                 {
6848 
6849                     /* Retry counter exceeded.  */
6850 
6851                     /* Enter IPCP failed state.  PPP must be stopped and started to try again.  */
6852                     ppp_ptr -> nx_ppp_ipcp_state =  NX_PPP_IPCP_FAILED_STATE;
6853 
6854                     /* Determine if the application has registered a link down notification
6855                        callback.  */
6856                     if (ppp_ptr -> nx_ppp_link_down_callback)
6857                     {
6858 
6859                         /* Yes, call the application's callback function.  */
6860                         (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
6861                     }
6862                 }
6863             }
6864 #ifndef NX_PPP_DISABLE_INFO
6865             else
6866             {
6867 
6868                 /* Increment the number of unhandled state machine events.   */
6869                 ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
6870             }
6871 #endif
6872             break;
6873         }
6874 
6875         default:
6876         {
6877 
6878 #ifndef NX_PPP_DISABLE_INFO
6879             {
6880 
6881                 /* Increment the number of unhandled state machine events.   */
6882                 ppp_ptr -> nx_ppp_ipcp_state_machine_unhandled_requests++;
6883             }
6884 #endif
6885             break;
6886         }
6887     }
6888 }
6889 
6890 
6891 /**************************************************************************/
6892 /*                                                                        */
6893 /*  FUNCTION                                               RELEASE        */
6894 /*                                                                        */
6895 /*    _nx_ppp_ipcp_configure_check                        PORTABLE C      */
6896 /*                                                           6.1.2        */
6897 /*  AUTHOR                                                                */
6898 /*                                                                        */
6899 /*    Yuxin Zhou, Microsoft Corporation                                   */
6900 /*                                                                        */
6901 /*  DESCRIPTION                                                           */
6902 /*                                                                        */
6903 /*    This function processes the IPCP message options.                   */
6904 /*                                                                        */
6905 /*  INPUT                                                                 */
6906 /*                                                                        */
6907 /*    ppp_ptr                               PPP instance pointer          */
6908 /*    packet_ptr                            IPCP packet pointer           */
6909 /*    naked_list                            NAKed option list             */
6910 /*    rejected_list                         Rejected option list          */
6911 /*    good_data                             Good options                  */
6912 /*                                                                        */
6913 /*  OUTPUT                                                                */
6914 /*                                                                        */
6915 /*    status                                                              */
6916 /*       NX_TRUE  1 indicates no errors, address obtained                 */
6917 /*       NX_FALSE 0 indicates an error or unknown option or address       */
6918 /*                                                                        */
6919 /*  CALLS                                                                 */
6920 /*                                                                        */
6921 /*    None                                                                */
6922 /*                                                                        */
6923 /*  CALLED BY                                                             */
6924 /*                                                                        */
6925 /*    _nx_ppp_ipcp_state_machine_update     IPCP state machine processing */
6926 /*                                                                        */
6927 /*  RELEASE HISTORY                                                       */
6928 /*                                                                        */
6929 /*    DATE              NAME                      DESCRIPTION             */
6930 /*                                                                        */
6931 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
6932 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
6933 /*                                            resulting in version 6.1    */
6934 /*  11-09-2020     Yuxin Zhou               Modified comment(s),          */
6935 /*                                            improved packet length      */
6936 /*                                            verification,               */
6937 /*                                            resulting in version 6.1.2  */
6938 /*                                                                        */
6939 /**************************************************************************/
_nx_ppp_ipcp_configure_check(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr,UCHAR * naked_list,UCHAR * rejected_list,UCHAR * good_data)6940 UINT  _nx_ppp_ipcp_configure_check(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr, UCHAR *naked_list, UCHAR *rejected_list, UCHAR *good_data)
6941 {
6942 
6943 UINT    length, ip_stat, status;
6944 UINT    i, w, m;
6945 UINT    nak_length = 0;
6946 UINT    rej_length = 0;
6947 UINT    good_index = 0;
6948 UINT    nak_index = 0;
6949 UINT    rej_index = 0;
6950 UCHAR   option;
6951 
6952 
6953     /* Extract the length. */
6954     length = ((UINT)(packet_ptr -> nx_packet_prepend_ptr[4] << 8) | (UINT)packet_ptr -> nx_packet_prepend_ptr[5]);
6955 
6956     /* Subtract 4 to remove the code, id, and length bytes from the length.  */
6957     length = length - 4;
6958 
6959     /* Initialize the rejected and naked lists. */
6960     rejected_list[0] =  naked_list[0] =  good_data[0] =  0;
6961 
6962     /* Loop to process the IPCP configuration options.  */
6963     for(w = 0, rej_index = 1, status = 1, nak_index = 1; (w + 2) <= length;)
6964     {
6965 
6966         UINT opt_length;
6967 
6968         /* Pickup the IPCP option.  */
6969         option =  packet_ptr -> nx_packet_prepend_ptr[w + 6];
6970 
6971         /* Pickup the IPCP option length.  */
6972         opt_length =  (UINT) packet_ptr -> nx_packet_prepend_ptr[w + 7];
6973 
6974         /* Determine if the length is valid.  */
6975         if ((opt_length < 2) || (opt_length > (length - w)))
6976         {
6977 
6978 #ifndef NX_PPP_DISABLE_INFO
6979 
6980             /* Increment the internal overflow counter.  */
6981             ppp_ptr -> nx_ppp_packet_overflow++;
6982 #endif
6983 
6984             /* Something is wrong, just get out of the loop!  */
6985             return(status);
6986         }
6987 
6988         /* Adjust the option length.  */
6989         opt_length -= 2;
6990 
6991         /* Process relative to the option.  */
6992         switch (option)
6993         {
6994 
6995             case NX_PPP_IP_ADDRESS_OPTION:
6996             {
6997 
6998                 /* Check if out of boundary.  */
6999                 if ((opt_length != 4) || ((good_index + 6) > NX_PPP_OPTION_MESSAGE_LENGTH))
7000                     return(NX_FALSE);
7001 
7002                 /* IP address option.  */
7003                 good_data[good_index++] =  NX_PPP_IP_ADDRESS_OPTION;
7004                 good_data[good_index++] =  6;
7005 
7006                 ip_stat =  0;
7007                 for(i = 0; i < 4; i++)
7008                 {
7009 
7010                     /* Pick up each byte of the IP address.  */
7011                     good_data[i + good_index] =  packet_ptr -> nx_packet_prepend_ptr[w + i + 8];
7012 
7013                     /* OR in the IP address bytes to make it easy to see if we got something.  */
7014                     ip_stat |=  good_data[i + good_index];
7015                 }
7016 
7017                 /* Adjust the main index.  */
7018                 w += 6;
7019 
7020                 /* Check if we really have an IP address.  */
7021                 if (!ip_stat)
7022                 {
7023 
7024                     /* Copy default IP address.  */
7025                     for(i = 0; i < 4; i++)
7026                     {
7027                         good_data[i + good_index] =  ppp_ptr -> nx_ppp_ipcp_peer_ip[i];
7028                     }
7029 
7030                     /* Setup NAK list so we can get the IP address hint.  */
7031                     for(i = 0; i < 6; i++)
7032                     {
7033                         naked_list[nak_index++] =  good_data[i];
7034                     }
7035 
7036                     nak_length = nak_index - 1;
7037 
7038                     /* Clear status.  */
7039                     status =  0;
7040                 }
7041                 else
7042                 {
7043 
7044                     /* We did get an IP address for the peer. Remember it!  */
7045                     for (i = 0; i < 4; i++)
7046                     {
7047 
7048                         /* Remember each byte of peer's IP address.  */
7049                         ppp_ptr -> nx_ppp_ipcp_peer_ip[i] =  good_data[i + good_index];
7050                     }
7051                 }
7052 
7053                 good_index += opt_length;
7054 
7055                 break;
7056              }
7057 
7058              case NX_PPP_IP_COMPRESSION_OPTION:
7059              {
7060 
7061                 /* IP Compression Option.  Since this is the receiver telling us what they
7062                    support it is not important to us since we don't support compression.  */
7063 
7064                 /* Simply adjust the main index into the option list.  */
7065                 w += (opt_length + 2); /* skip */
7066                 break;
7067              }
7068 
7069             case NX_PPP_DNS_SERVER_OPTION:
7070              {
7071 
7072                 /* Check if out of boundary.  */
7073                 if ((opt_length != 4) || ((good_index + 6) > NX_PPP_OPTION_MESSAGE_LENGTH))
7074                     return(NX_FALSE);
7075 
7076                  /* Only request a hint if we don't have already have a dns address . */
7077                  good_data[good_index++] =  NX_PPP_DNS_SERVER_OPTION;
7078                  good_data[good_index++] =  6;
7079                  ip_stat =  0;
7080                  for(i = 0; i < 4; i++)
7081                  {
7082 
7083                      /* Pick up each byte of the primary DNS address.  */
7084                      good_data[i + good_index] =  packet_ptr -> nx_packet_prepend_ptr[w + i + 8];
7085 
7086                      /* Or in the IP address bytes to make it easy to see if we got something.  */
7087                      ip_stat |=  good_data[i + good_index];
7088                  }
7089 
7090                  /* Adjust the main index.  */
7091                  w += 6;
7092 
7093                  /* Check if we really have an primary DNS address.  */
7094                  if (!ip_stat)
7095                  {
7096 
7097 
7098                      /* Update the number of retries on secondary  address requests. */
7099                      ppp_ptr -> nx_ppp_dns_address_retries++;
7100 
7101                      /* Check if we have reached the limit on retries. */
7102                      if (ppp_ptr -> nx_ppp_dns_address_retries >= NX_PPP_DNS_ADDRESS_MAX_RETRIES)
7103                      {
7104                          /* We have. Return successful result and let IPCP complete. */
7105                          break;
7106                      }
7107 
7108                     /* Copy default DNS IP address.  */
7109                      good_data[good_index] =  (UCHAR) (ppp_ptr -> nx_ppp_primary_dns_address >> 24);
7110                      good_data[good_index + 1] =  (UCHAR) ((ppp_ptr -> nx_ppp_primary_dns_address >> 16) & 0xff);
7111                      good_data[good_index + 2] = (UCHAR) ((ppp_ptr -> nx_ppp_primary_dns_address >> 8) & 0xff);
7112                      good_data[good_index + 3]= (UCHAR) (ppp_ptr -> nx_ppp_primary_dns_address & 0xff);
7113 
7114                     /* Setup NAK list so we can get the DNS IP address hint.  */
7115                     for(i = 0; i < 6; i++)
7116                     {
7117                         naked_list[nak_index++] =  good_data[good_index + i - 2];
7118                     }
7119 
7120                      /* Clear status.  */
7121                      status =  0;
7122 
7123                      /* Update the size of the nak and reject data. */
7124                      nak_length = nak_index - 1;
7125                  }
7126                  else
7127                  {
7128 
7129                      /* Copy good IP address.  */
7130                      ppp_ptr -> nx_ppp_primary_dns_address = ((ULONG)good_data[good_index] << 24) & 0xFF000000;
7131                      ppp_ptr -> nx_ppp_primary_dns_address |= (good_data[good_index + 1] << 16) & 0x00FF0000;
7132                      ppp_ptr -> nx_ppp_primary_dns_address |= (good_data[good_index + 2] << 8) & 0x0000FF00;
7133                      ppp_ptr -> nx_ppp_primary_dns_address |= good_data[good_index + 3] & 0x000000FF;
7134                  }
7135 
7136                  good_index += opt_length;
7137 
7138                  break;
7139              }
7140 
7141              case NX_PPP_DNS_SECONDARY_SERVER_OPTION:
7142              {
7143 
7144                 /* Check if out of boundary.  */
7145                 if ((opt_length != 4) || ((good_index + 6) > NX_PPP_OPTION_MESSAGE_LENGTH))
7146                     return(NX_FALSE);
7147 
7148                  /* Only request a hint if we don't have already have a dns address . */
7149                  good_data[good_index++] =  NX_PPP_DNS_SECONDARY_SERVER_OPTION;
7150                  good_data[good_index++] =  6;
7151                  ip_stat =  0;
7152                  for(i = 0; i < 4; i++)
7153                  {
7154 
7155                      /* Pick up each byte of the secondary DNS address.  */
7156                      good_data[i + good_index] =  packet_ptr -> nx_packet_prepend_ptr[w + i + 8];
7157 
7158                      /* Or in the IP address bytes to make it easy to see if we got something.  */
7159                      ip_stat |=  good_data[i + good_index];
7160                  }
7161 
7162                  /* Adjust the main index.  */
7163                  w += 6;
7164 
7165                  /* Check if we really have an primary DNS address.  */
7166                  if (!ip_stat)
7167                  {
7168 
7169                      /* Update the number of retries on primary address requests. */
7170                      ppp_ptr -> nx_ppp_secondary_dns_address_retries++;
7171 
7172                      /* Check if we have reached the limit on retries. */
7173                      if (ppp_ptr -> nx_ppp_secondary_dns_address_retries >= NX_PPP_DNS_ADDRESS_MAX_RETRIES)
7174                      {
7175                          /* We have. Return successful result and let IPCP complete. */
7176                          break;
7177                      }
7178 
7179                     /* Copy the primary DNS IP address from the packet data.  */
7180                      good_data[good_index] =  (UCHAR) (ppp_ptr -> nx_ppp_secondary_dns_address >> 24);
7181                      good_data[good_index + 1] =  (UCHAR) ((ppp_ptr -> nx_ppp_secondary_dns_address >> 16) & 0xff);
7182                      good_data[good_index + 2] = (UCHAR) ((ppp_ptr -> nx_ppp_secondary_dns_address >> 8) & 0xff);
7183                      good_data[good_index + 3]= (UCHAR) (ppp_ptr -> nx_ppp_secondary_dns_address & 0xff);
7184 
7185                     /* Setup NAK list so we can get the DNS IP address hint.  */
7186                     for(i = 0; i < 6; i++)
7187                     {
7188                         naked_list[nak_index++] =  good_data[good_index + i - 2];
7189                     }
7190 
7191                      /* Clear status.  */
7192                      status =  0;
7193 
7194                      /* Update the size of the nak and reject data. */
7195                      nak_length = nak_index - 1;
7196                  }
7197 
7198                  else
7199                  {
7200 
7201                      /* Copy good IP address.  */
7202                      ppp_ptr -> nx_ppp_secondary_dns_address = ((ULONG)good_data[good_index] << 24) & 0xFF000000;
7203                      ppp_ptr -> nx_ppp_secondary_dns_address |= (good_data[good_index + 1] << 16) & 0x00FF0000;
7204                      ppp_ptr -> nx_ppp_secondary_dns_address |= (good_data[good_index + 2] << 8) & 0x0000FF00;
7205                      ppp_ptr -> nx_ppp_secondary_dns_address |= good_data[good_index + 3] & 0x000000FF;
7206                  }
7207 
7208                  good_index += opt_length;
7209 
7210                  break;
7211              }
7212 
7213             default:
7214             {
7215 
7216                 /* All other options get NAKed. */
7217                 status = 0;
7218 
7219                 /* Determine if the option will fit.  */
7220                 if ((rej_index + opt_length + 2) >= NX_PPP_OPTION_MESSAGE_LENGTH)
7221                 {
7222 
7223 #ifndef NX_PPP_DISABLE_INFO
7224 
7225                     /* Increment the internal overflow counter.  */
7226                     ppp_ptr -> nx_ppp_packet_overflow++;
7227 #endif
7228 
7229                     /* Return status.  */
7230                     return(status);
7231                 }
7232 
7233                 /* Place the option in the rejected list.  */
7234                 rejected_list[rej_index++] = option;
7235                 rejected_list[rej_index++] = (UCHAR)(opt_length + 2);
7236 
7237                 /* Loop to copy the rest of the options into the rejected list.  */
7238                 for (m = 0; m < opt_length; m++)
7239                 {
7240 
7241                     /* Copy option byte into the rejected option list.  */
7242                     rejected_list[rej_index] =  packet_ptr -> nx_packet_prepend_ptr[w + m + 8];
7243                     rej_index++;
7244                 }
7245 
7246                 rej_length = rej_index - 1;
7247 
7248                 /* Adjust the main index into the option list.  */
7249                 w += (opt_length + 2); /* skip */
7250                 break;
7251             }
7252         }
7253     }
7254 
7255     /* Setup the length in the naked and rejected lists.  */
7256     naked_list[0] = (UCHAR)nak_length;
7257     rejected_list[0] = (UCHAR)rej_length;
7258 
7259     /* Return status.  */
7260     return(status);
7261 }
7262 
7263 
7264 /**************************************************************************/
7265 /*                                                                        */
7266 /*  FUNCTION                                               RELEASE        */
7267 /*                                                                        */
7268 /*    _nx_ppp_ipcp_configure_request_send                 PORTABLE C      */
7269 /*                                                           6.1          */
7270 /*  AUTHOR                                                                */
7271 /*                                                                        */
7272 /*    Yuxin Zhou, Microsoft Corporation                                   */
7273 /*                                                                        */
7274 /*  DESCRIPTION                                                           */
7275 /*                                                                        */
7276 /*    This function builds a configure request message and sends it out.  */
7277 /*                                                                        */
7278 /*  INPUT                                                                 */
7279 /*                                                                        */
7280 /*    ppp_ptr                               PPP instance pointer          */
7281 /*    negotiate_list                        List of options to negotiate  */
7282 /*                                                                        */
7283 /*  OUTPUT                                                                */
7284 /*                                                                        */
7285 /*    None                                                                */
7286 /*                                                                        */
7287 /*  CALLS                                                                 */
7288 /*                                                                        */
7289 /*    nx_packet_allocate                    Allocate a packet for sending */
7290 /*    _nx_ppp_packet_transmit               Send IPCP packet              */
7291 /*                                                                        */
7292 /*  CALLED BY                                                             */
7293 /*                                                                        */
7294 /*    _nx_ppp_ipcp_state_machine_update     IPCP state machine processing */
7295 /*                                                                        */
7296 /*  RELEASE HISTORY                                                       */
7297 /*                                                                        */
7298 /*    DATE              NAME                      DESCRIPTION             */
7299 /*                                                                        */
7300 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7301 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7302 /*                                            resulting in version 6.1    */
7303 /*                                                                        */
7304 /**************************************************************************/
_nx_ppp_ipcp_configure_request_send(NX_PPP * ppp_ptr,UCHAR * negotiate_list)7305 void  _nx_ppp_ipcp_configure_request_send(NX_PPP *ppp_ptr, UCHAR *negotiate_list)
7306 {
7307 
7308 UINT        status, i;
7309 NX_PACKET   *packet_ptr;
7310 UINT        index;
7311 
7312 
7313     /* Allocate a packet for the IPCP packet.  */
7314     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
7315 
7316     /* Determine if the packet was allocated successfully.  */
7317     if (status != NX_SUCCESS)
7318     {
7319 
7320 #ifndef NX_PPP_DISABLE_INFO
7321 
7322         /* Increment the number of packet allocation timeouts.  */
7323         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
7324 #endif
7325 
7326         /* An error was detected, simply return a NULL pointer.  */
7327         return;
7328     }
7329 
7330     /* Clear the packet memory.*/
7331     memset(packet_ptr -> nx_packet_prepend_ptr, 0, (UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr));
7332 
7333     /* Adjust the transmit ID.  */
7334     ppp_ptr -> nx_ppp_transmit_id++;
7335 
7336     /* Build IPCP request message.  */
7337     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_IPCP_PROTOCOL & 0xFF00) >> 8;
7338     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_IPCP_PROTOCOL & 0xFF;
7339     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_IPCP_CONFIGURE_REQUEST;
7340     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_transmit_id;
7341     packet_ptr -> nx_packet_prepend_ptr[4] =  0x00;
7342     packet_ptr -> nx_packet_prepend_ptr[5] =  0x0A;  /* Size of the IPCP data */
7343     packet_ptr -> nx_packet_prepend_ptr[6] =  0x03;
7344     packet_ptr -> nx_packet_prepend_ptr[7] =  0x06;
7345 
7346     /* Load up the default IP address.  */
7347     for(i = 0; i < 4; i++)
7348     {
7349 
7350         /* Copy byte of IP address.  */
7351         packet_ptr -> nx_packet_prepend_ptr[i+8] =  ppp_ptr -> nx_ppp_ipcp_local_ip[i];
7352     }
7353 
7354     index = i + 8;
7355 
7356     /* Determine if we want the DNS option ...  */
7357     if (negotiate_list[0] == 0)
7358     {
7359 
7360         /* Yes (because it is not obvious from the code style), let's try to get the DNS server.  */
7361 
7362         /* Update the IPCP length for DNS address.  */
7363         packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR)(packet_ptr -> nx_packet_prepend_ptr[5] + 6);
7364 
7365         /* Add the option for retrieving the DNS server as well.  */
7366         packet_ptr -> nx_packet_prepend_ptr[index] = NX_PPP_DNS_SERVER_OPTION;
7367         packet_ptr -> nx_packet_prepend_ptr[index+1] = 0x06;
7368         packet_ptr -> nx_packet_prepend_ptr[index+2] = (UCHAR) (ppp_ptr -> nx_ppp_primary_dns_address >> 24);
7369         packet_ptr -> nx_packet_prepend_ptr[index+3] = (UCHAR) ((ppp_ptr -> nx_ppp_primary_dns_address >> 16) & 0xff);
7370         packet_ptr -> nx_packet_prepend_ptr[index+4] = (UCHAR) ((ppp_ptr -> nx_ppp_primary_dns_address >> 8) & 0xff);
7371         packet_ptr -> nx_packet_prepend_ptr[index+5] = (UCHAR) (ppp_ptr -> nx_ppp_primary_dns_address & 0xff);
7372         index += 6;
7373 
7374         /* Also check for a secondary DNS address request. */
7375         if (negotiate_list[1] == 0)
7376         {
7377 
7378             /* Update the IPCP length for secondary DNS address.  */
7379             packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR)(packet_ptr -> nx_packet_prepend_ptr[5] + 6);
7380 
7381             /* Add the option for retrieving the DNS server as well.  */
7382             packet_ptr -> nx_packet_prepend_ptr[index] = NX_PPP_DNS_SECONDARY_SERVER_OPTION;
7383             packet_ptr -> nx_packet_prepend_ptr[index+1] = 0x06;
7384             packet_ptr -> nx_packet_prepend_ptr[index+2] = (UCHAR) (ppp_ptr -> nx_ppp_secondary_dns_address >> 24);
7385             packet_ptr -> nx_packet_prepend_ptr[index+3] = (UCHAR) ((ppp_ptr -> nx_ppp_secondary_dns_address >> 16) & 0xff);
7386             packet_ptr -> nx_packet_prepend_ptr[index+4] = (UCHAR) ((ppp_ptr -> nx_ppp_secondary_dns_address >> 8) & 0xff);
7387             packet_ptr -> nx_packet_prepend_ptr[index+5] = (UCHAR) (ppp_ptr -> nx_ppp_secondary_dns_address & 0xff);
7388             index += 6;
7389         }
7390     }
7391 
7392     /* Setup the append pointer and the packet length.  */
7393     packet_ptr -> nx_packet_length =  index;
7394 
7395     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
7396 
7397 #ifndef NX_PPP_DISABLE_INFO
7398 
7399     /* Increment the number of IPCP frames sent.  */
7400     ppp_ptr -> nx_ppp_ipcp_frames_sent++;
7401 
7402     /* Increment the number of IPCP configure requests sent.  */
7403     ppp_ptr -> nx_ppp_ipcp_configure_requests_sent++;
7404 #endif
7405 
7406     /* Send IPCP configure request packet.  */
7407     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
7408 }
7409 
7410 
7411 /**************************************************************************/
7412 /*                                                                        */
7413 /*  FUNCTION                                               RELEASE        */
7414 /*                                                                        */
7415 /*    _nx_ppp_ipcp_response_extract                       PORTABLE C      */
7416 /*                                                           6.1.2        */
7417 /*  AUTHOR                                                                */
7418 /*                                                                        */
7419 /*    Yuxin Zhou, Microsoft Corporation                                   */
7420 /*                                                                        */
7421 /*  DESCRIPTION                                                           */
7422 /*                                                                        */
7423 /*    This function extracts information from the IPCP response           */
7424 /*    message.                                                            */
7425 /*                                                                        */
7426 /*  INPUT                                                                 */
7427 /*                                                                        */
7428 /*    ppp_ptr                               PPP instance pointer          */
7429 /*    packet_ptr                            Pointer to IPCP packet        */
7430 /*                                                                        */
7431 /*  OUTPUT                                                                */
7432 /*                                                                        */
7433 /*    None                                                                */
7434 /*                                                                        */
7435 /*  CALLS                                                                 */
7436 /*                                                                        */
7437 /*    None                                                                */
7438 /*                                                                        */
7439 /*  CALLED BY                                                             */
7440 /*                                                                        */
7441 /*    _nx_ppp_ipcp_state_machine_update     IPCP state machine processing */
7442 /*                                                                        */
7443 /*  RELEASE HISTORY                                                       */
7444 /*                                                                        */
7445 /*    DATE              NAME                      DESCRIPTION             */
7446 /*                                                                        */
7447 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7448 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7449 /*                                            resulting in version 6.1    */
7450 /*  11-09-2020     Yuxin Zhou               Modified comment(s),          */
7451 /*                                            improved packet length      */
7452 /*                                            verification,               */
7453 /*                                            resulting in version 6.1.2  */
7454 /*                                                                        */
7455 /**************************************************************************/
_nx_ppp_ipcp_response_extract(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)7456 void  _nx_ppp_ipcp_response_extract(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
7457 {
7458 
7459 UINT    i, j;
7460 ULONG   length;
7461 
7462 
7463 
7464     /* Search for IP address and DNS address in response.  */
7465 
7466     /* Setup the packet length.  */
7467     length =  (((ULONG) packet_ptr -> nx_packet_prepend_ptr[4]) << 8) | ((ULONG) packet_ptr -> nx_packet_prepend_ptr[5]);
7468 
7469     /* Subtract the request type, id, and length.  */
7470     if (length >= 4)
7471         length =  length - 4;
7472     else
7473         length =  0;
7474 
7475     /* Loop to parse the options to look for primary DNS address.  */
7476     i =  6;
7477     while (length)
7478     {
7479 
7480         /* Subtract the length.  */
7481         if (length >= ((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+1]))
7482             length =  length - ((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+1]);
7483         else
7484             length =  0;
7485 
7486         /* Check for the IP address.  */
7487         if (packet_ptr -> nx_packet_prepend_ptr[i] == NX_PPP_IP_ADDRESS_OPTION)
7488         {
7489 
7490 
7491             /* Copy the IP address bytes into the PPP storage.  */
7492             for(j = 0; j < 4; j++)
7493             {
7494 
7495                 /* Copy a byte of the IP address. */
7496                 ppp_ptr -> nx_ppp_ipcp_local_ip[j] =  packet_ptr -> nx_packet_prepend_ptr[i+j+2];
7497             }
7498         }
7499 
7500         /* Check for the primary DNS option. */
7501         else if (packet_ptr -> nx_packet_prepend_ptr[i] == NX_PPP_DNS_SERVER_OPTION)
7502         {
7503 
7504             /* Yes, we have a primary DNS address.  */
7505 
7506             /* Let's copy it into the PPP structure in case we need it later.  */
7507             ppp_ptr -> nx_ppp_primary_dns_address =  ((((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+2]) << 24) |
7508                                                      (((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+3]) << 16) |
7509                                                      (((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+4]) << 8)  |
7510                                                       ((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+5]));
7511 
7512         }
7513 
7514         /* Check for the primary DNS option. */
7515         else if (packet_ptr -> nx_packet_prepend_ptr[i] == NX_PPP_DNS_SECONDARY_SERVER_OPTION)
7516         {
7517 
7518             /* Yes, we have a secondary DNS address.  */
7519 
7520             /* Let's copy it into the PPP structure in case we need it later.  */
7521             ppp_ptr -> nx_ppp_secondary_dns_address =  ((((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+2]) << 24) |
7522                                                      (((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+3]) << 16) |
7523                                                      (((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+4]) << 8)  |
7524                                                       ((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+5]));
7525 
7526 
7527             /* Break out of the loop.  */
7528             break;
7529         }
7530 
7531         /* Otherwise move to the next option. */
7532         if (length >= ((ULONG) packet_ptr -> nx_packet_prepend_ptr[i+1]))
7533         {
7534 
7535             /* Yes, there is another option.  */
7536 
7537             /* Position to the next option.  */
7538             i =  i + (((UINT) packet_ptr -> nx_packet_prepend_ptr[i+1]));
7539         }
7540         else
7541         {
7542 
7543             /* Make sure the length is 0.  */
7544             length =  0;
7545         }
7546     }
7547 }
7548 
7549 
7550 /**************************************************************************/
7551 /*                                                                        */
7552 /*  FUNCTION                                               RELEASE        */
7553 /*                                                                        */
7554 /*    _nx_ppp_ipcp_response_send                          PORTABLE C      */
7555 /*                                                           6.1          */
7556 /*  AUTHOR                                                                */
7557 /*                                                                        */
7558 /*    Yuxin Zhou, Microsoft Corporation                                   */
7559 /*                                                                        */
7560 /*  DESCRIPTION                                                           */
7561 /*                                                                        */
7562 /*    This function builds and sends an IPCP response message.            */
7563 /*                                                                        */
7564 /*  INPUT                                                                 */
7565 /*                                                                        */
7566 /*    ppp_ptr                               PPP instance pointer          */
7567 /*    type                                  ACK or NAK selection          */
7568 /*    data                                  Previous IPCP message         */
7569 /*    length                                Length of previous IPCP msg   */
7570 /*    packet_ptr                            Request packet pointer        */
7571 /*                                                                        */
7572 /*  OUTPUT                                                                */
7573 /*                                                                        */
7574 /*    None                                                                */
7575 /*                                                                        */
7576 /*  CALLS                                                                 */
7577 /*                                                                        */
7578 /*    nx_packet_allocate                    Allocate a packet for sending */
7579 /*    _nx_ppp_packet_transmit               Send frame                    */
7580 /*                                                                        */
7581 /*  CALLED BY                                                             */
7582 /*                                                                        */
7583 /*    _nx_ppp_ipcp_state_machine_update     IPCP state machine processing */
7584 /*                                                                        */
7585 /*  RELEASE HISTORY                                                       */
7586 /*                                                                        */
7587 /*    DATE              NAME                      DESCRIPTION             */
7588 /*                                                                        */
7589 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7590 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7591 /*                                            resulting in version 6.1    */
7592 /*                                                                        */
7593 /**************************************************************************/
_nx_ppp_ipcp_response_send(NX_PPP * ppp_ptr,UCHAR type,UCHAR * data,UCHAR length,NX_PACKET * cfg_packet_ptr)7594 void  _nx_ppp_ipcp_response_send(NX_PPP *ppp_ptr, UCHAR type, UCHAR *data, UCHAR length, NX_PACKET *cfg_packet_ptr)
7595 {
7596 
7597 UINT        status, i;
7598 NX_PACKET   *packet_ptr;
7599 
7600 
7601     /* Allocate a packet for the IPCP packet.  */
7602     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
7603 
7604     /* Determine if the packet was allocated successfully.  */
7605     if (status != NX_SUCCESS)
7606     {
7607 
7608 #ifndef NX_PPP_DISABLE_INFO
7609 
7610         /* Increment the number of packet allocation timeouts.  */
7611         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
7612 #endif
7613 
7614         /* An error was detected, simply return a NULL pointer.  */
7615         return;
7616     }
7617 
7618     /* Determine if an ACK is requested.  */
7619     if (type == NX_PPP_IPCP_CONFIGURE_ACK)
7620     {
7621 
7622         /* Check if out of boundary.  */
7623         if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(cfg_packet_ptr -> nx_packet_length))
7624         {
7625 
7626             /* Release the packet.  */
7627             nx_packet_release(packet_ptr);
7628             return;
7629         }
7630 
7631         /* Yes, an ACK is requested.  Simply copy the config packet into the new packet and change
7632            the type. */
7633         for (i = 0; i < cfg_packet_ptr -> nx_packet_length; i++)
7634         {
7635 
7636             /* Determine if the copy exceeds the payload.  */
7637             if (&packet_ptr -> nx_packet_prepend_ptr[i] >= packet_ptr -> nx_packet_data_end)
7638             {
7639 
7640 #ifndef NX_PPP_DISABLE_INFO
7641 
7642                 /* Increment the internal error counter.  */
7643                 ppp_ptr -> nx_ppp_internal_errors++;
7644 #endif
7645 
7646                 /* Release the packet.  */
7647                 nx_packet_release(packet_ptr);
7648 
7649                 /* Simply return.  */
7650                 return;
7651             }
7652 
7653             /* Copy one byte.  */
7654             packet_ptr -> nx_packet_prepend_ptr[i] =  cfg_packet_ptr -> nx_packet_prepend_ptr[i];
7655         }
7656 
7657         /* Adjust the type of the new packet to represent an ACK.  */
7658         packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_IPCP_CONFIGURE_ACK;
7659 
7660         /* Adjust the length and append pointers of the packet.  */
7661         packet_ptr -> nx_packet_length =  cfg_packet_ptr -> nx_packet_length;
7662         packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
7663     }
7664     else
7665     {
7666 
7667         /* Check if out of boundary.  */
7668         if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(length + 6))
7669         {
7670 
7671             /* Release the packet.  */
7672             nx_packet_release(packet_ptr);
7673             return;
7674         }
7675 
7676         /* Build IPCP response message.  */
7677         packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_IPCP_PROTOCOL & 0xFF00) >> 8;
7678         packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_IPCP_PROTOCOL & 0xFF;
7679         packet_ptr -> nx_packet_prepend_ptr[2] =  type;
7680         packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_receive_id;
7681         packet_ptr -> nx_packet_prepend_ptr[4] =  0x00;
7682         packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR)(length + 4);
7683 
7684         /* Load up the default IP address.  */
7685         for(i = 0; i < length; i++)
7686         {
7687 
7688             /* Copy byte of IP address.  */
7689             packet_ptr -> nx_packet_prepend_ptr[i+6] =  data[i];
7690         }
7691 
7692         /* Setup the append pointer and the packet length.  */
7693         packet_ptr -> nx_packet_length =  (UCHAR)(length + 4 + 2);
7694         packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
7695     }
7696 
7697 #ifndef NX_PPP_DISABLE_INFO
7698 
7699     /* Increment the number of IPCP frames sent.  */
7700     ppp_ptr -> nx_ppp_ipcp_frames_sent++;
7701 
7702     /* Increment counters based on type of response.  */
7703     if (type == NX_PPP_IPCP_CONFIGURE_ACK)
7704     {
7705 
7706         /* Increment the number of IPCP configure ACKs sent.  */
7707         ppp_ptr -> nx_ppp_ipcp_configure_acks_sent++;
7708     }
7709     else if (type == NX_PPP_IPCP_CONFIGURE_NAK)
7710     {
7711 
7712         /* Increment the number of IPCP configure NAKs sent.  */
7713         ppp_ptr -> nx_ppp_ipcp_configure_naks_sent++;
7714     }
7715     else if (type == NX_PPP_IPCP_CONFIGURE_REJECT)
7716     {
7717 
7718         /* Increment the number of IPCP configure rejects sent.  */
7719         ppp_ptr -> nx_ppp_ipcp_configure_rejects_sent++;
7720     }
7721 #endif
7722 
7723     /* Send IPCP response.  */
7724     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
7725 }
7726 
7727 
7728 /**************************************************************************/
7729 /*                                                                        */
7730 /*  FUNCTION                                               RELEASE        */
7731 /*                                                                        */
7732 /*    _nx_ppp_ipcp_terminate_send                         PORTABLE C      */
7733 /*                                                           6.1          */
7734 /*  AUTHOR                                                                */
7735 /*                                                                        */
7736 /*    Yuxin Zhou, Microsoft Corporation                                   */
7737 /*                                                                        */
7738 /*  DESCRIPTION                                                           */
7739 /*                                                                        */
7740 /*    This function builds a terminate request message and sends          */
7741 /*    it out.                                                             */
7742 /*                                                                        */
7743 /*  INPUT                                                                 */
7744 /*                                                                        */
7745 /*    ppp_ptr                               PPP instance pointer          */
7746 /*                                                                        */
7747 /*  OUTPUT                                                                */
7748 /*                                                                        */
7749 /*    None                                                                */
7750 /*                                                                        */
7751 /*  CALLS                                                                 */
7752 /*                                                                        */
7753 /*    nx_packet_allocate                    Allocate a packet for sending */
7754 /*    _nx_ppp_packet_transmit               Send AHDLC packet             */
7755 /*                                                                        */
7756 /*  CALLED BY                                                             */
7757 /*                                                                        */
7758 /*    _nx_ppp_ipcp_state_machine_update     IPCP state machine processing */
7759 /*                                                                        */
7760 /*  RELEASE HISTORY                                                       */
7761 /*                                                                        */
7762 /*    DATE              NAME                      DESCRIPTION             */
7763 /*                                                                        */
7764 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7765 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7766 /*                                            resulting in version 6.1    */
7767 /*                                                                        */
7768 /**************************************************************************/
_nx_ppp_ipcp_terminate_send(NX_PPP * ppp_ptr)7769 void  _nx_ppp_ipcp_terminate_send(NX_PPP *ppp_ptr)
7770 {
7771 
7772 UINT        status;
7773 NX_PACKET   *packet_ptr;
7774 
7775 
7776     /* Allocate a packet for the IPCP packet.  */
7777     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
7778 
7779     /* Determine if the packet was allocated successfully.  */
7780     if (status != NX_SUCCESS)
7781     {
7782 
7783 #ifndef NX_PPP_DISABLE_INFO
7784 
7785         /* Increment the number of packet allocation timeouts.  */
7786         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
7787 #endif
7788 
7789         /* An error was detected, simply return a NULL pointer.  */
7790         return;
7791     }
7792 
7793     /* Build IPCP terminate message.  */
7794     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_IPCP_PROTOCOL & 0xFF00) >> 8;
7795     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_IPCP_PROTOCOL & 0xFF;
7796     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_IPCP_TERMINATE_REQUEST;
7797     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_transmit_id;
7798     packet_ptr -> nx_packet_prepend_ptr[4] =  0x00;
7799     packet_ptr -> nx_packet_prepend_ptr[5] =  0x04;
7800 
7801     /* Setup the append pointer and the packet length.  */
7802     packet_ptr -> nx_packet_length = 6;
7803     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
7804 
7805 #ifndef NX_PPP_DISABLE_INFO
7806 
7807     /* Increment the number of IPCP frames sent.  */
7808     ppp_ptr -> nx_ppp_ipcp_frames_sent++;
7809 
7810     /* Increment the number of IPCP terminate sent.  */
7811     ppp_ptr -> nx_ppp_ipcp_terminate_requests_sent++;
7812 #endif
7813 
7814     /* Send IPCP terminate packet.  */
7815     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
7816 }
7817 
7818 
7819 /**************************************************************************/
7820 /*                                                                        */
7821 /*  FUNCTION                                               RELEASE        */
7822 /*                                                                        */
7823 /*    _nx_ppp_ipcp_terminate_ack_send                     PORTABLE C      */
7824 /*                                                           6.1          */
7825 /*  AUTHOR                                                                */
7826 /*                                                                        */
7827 /*    Yuxin Zhou, Microsoft Corporation                                   */
7828 /*                                                                        */
7829 /*  DESCRIPTION                                                           */
7830 /*                                                                        */
7831 /*    This function builds a terminate ACK request message and sends      */
7832 /*    it out.                                                             */
7833 /*                                                                        */
7834 /*  INPUT                                                                 */
7835 /*                                                                        */
7836 /*    ppp_ptr                               PPP instance pointer          */
7837 /*                                                                        */
7838 /*  OUTPUT                                                                */
7839 /*                                                                        */
7840 /*    None                                                                */
7841 /*                                                                        */
7842 /*  CALLS                                                                 */
7843 /*                                                                        */
7844 /*    nx_packet_allocate                    Allocate a packet for sending */
7845 /*    _nx_ppp_packet_transmit               Send AHDLC packet             */
7846 /*                                                                        */
7847 /*  CALLED BY                                                             */
7848 /*                                                                        */
7849 /*    _nx_ppp_ipcp_state_machine_update     IPCP state machine processing */
7850 /*                                                                        */
7851 /*  RELEASE HISTORY                                                       */
7852 /*                                                                        */
7853 /*    DATE              NAME                      DESCRIPTION             */
7854 /*                                                                        */
7855 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7856 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7857 /*                                            resulting in version 6.1    */
7858 /*                                                                        */
7859 /**************************************************************************/
_nx_ppp_ipcp_terminate_ack_send(NX_PPP * ppp_ptr)7860 void  _nx_ppp_ipcp_terminate_ack_send(NX_PPP *ppp_ptr)
7861 {
7862 
7863 UINT        status;
7864 NX_PACKET   *packet_ptr;
7865 
7866 
7867     /* Allocate a packet for the IPCP packet.  */
7868     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
7869 
7870     /* Determine if the packet was allocated successfully.  */
7871     if (status != NX_SUCCESS)
7872     {
7873 
7874 #ifndef NX_PPP_DISABLE_INFO
7875 
7876         /* Increment the number of packet allocation timeouts.  */
7877         ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
7878 #endif
7879 
7880         /* An error was detected, simply return a NULL pointer.  */
7881         return;
7882     }
7883 
7884     /* Build IPCP terminate ACK message.  */
7885     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_IPCP_PROTOCOL & 0xFF00) >> 8;
7886     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_IPCP_PROTOCOL & 0xFF;
7887     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_IPCP_TERMINATE_ACK;
7888     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_receive_id;
7889     packet_ptr -> nx_packet_prepend_ptr[4] =  0x00;
7890     packet_ptr -> nx_packet_prepend_ptr[5] =  0x04;
7891 
7892     /* Setup the append pointer and the packet length.  */
7893     packet_ptr -> nx_packet_length = 6;
7894     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
7895 
7896 #ifndef NX_PPP_DISABLE_INFO
7897 
7898     /* Increment the number of IPCP frames sent.  */
7899     ppp_ptr -> nx_ppp_ipcp_frames_sent++;
7900 
7901     /* Increment the number of IPCP terminate ACKs sent.  */
7902     ppp_ptr -> nx_ppp_ipcp_terminate_acks_sent++;
7903 #endif
7904 
7905     /* Send IPCP terminate ACK packet.  */
7906     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
7907 }
7908 
7909 
7910 /**************************************************************************/
7911 /*                                                                        */
7912 /*  FUNCTION                                               RELEASE        */
7913 /*                                                                        */
7914 /*    _nx_ppp_packet_transmit                             PORTABLE C      */
7915 /*                                                           6.1          */
7916 /*  AUTHOR                                                                */
7917 /*                                                                        */
7918 /*    Yuxin Zhou, Microsoft Corporation                                   */
7919 /*                                                                        */
7920 /*  DESCRIPTION                                                           */
7921 /*                                                                        */
7922 /*    This function adds a CRC to the current transmit buffer and then    */
7923 /*    sends the buffer via the user supplied byte output routine.         */
7924 /*                                                                        */
7925 /*  INPUT                                                                 */
7926 /*                                                                        */
7927 /*    ppp_ptr                               Pointer to PPP instance       */
7928 /*    packet_ptr                            Pointer to PPP packet         */
7929 /*                                                                        */
7930 /*  OUTPUT                                                                */
7931 /*                                                                        */
7932 /*    None                                                                */
7933 /*                                                                        */
7934 /*  CALLS                                                                 */
7935 /*                                                                        */
7936 /*    [_nx_ppp_debug_log_capture]           Put send frame in debug log   */
7937 /*    _nx_ppp_crc_append                    Add PPP CRC                   */
7938 /*    (nx_ppp_byte_send)                    User supplied byte send       */
7939 /*    nx_packet_transmit_release            Release the transmit packet   */
7940 /*                                                                        */
7941 /*  CALLED BY                                                             */
7942 /*                                                                        */
7943 /*    _nx_ppp_process_deferred_ip_packet_send  Process deferred IP packet */
7944 /*    _nx_ppp_lcp_code_reject               Send LCP code reject message  */
7945 /*    _nx_ppp_lcp_configure_reply_send      Send LCP configure reply      */
7946 /*    _nx_ppp_lcp_configure_request_send    Send LCP configure request    */
7947 /*    _nx_ppp_lcp_terminate_ack_send        Send LCP terminate ACK        */
7948 /*    _nx_ppp_lcp_terminate_request_send    Send LCP terminate request    */
7949 /*    _nx_ppp_pap_authentication_request    PAP authentication request    */
7950 /*    _nx_ppp_pap_authentication_ack        PAP authentication ACK        */
7951 /*    _nx_ppp_pap_authentication_nak        PAP authentication NAK        */
7952 /*    _nx_ppp_chap_challenge_send           CHAP challenge send           */
7953 /*    _nx_ppp_chap_challenge_respond        CHAP challenge respond        */
7954 /*    _nx_ppp_chap_challenge_validate       CHAP challenge validate       */
7955 /*    _nx_ppp_ipcp_configure_request_send   Send IPCP configure request   */
7956 /*    _nx_ppp_ipcp_response_send            Send IPCP response            */
7957 /*    _nx_ppp_ipcp_terminate_send           Send IPCP terminate           */
7958 /*    _nx_ppp_ipcp_terminate_ack_send       Send IPCP terminate ACK       */
7959 /*                                                                        */
7960 /*  RELEASE HISTORY                                                       */
7961 /*                                                                        */
7962 /*    DATE              NAME                      DESCRIPTION             */
7963 /*                                                                        */
7964 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
7965 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
7966 /*                                            resulting in version 6.1    */
7967 /*                                                                        */
7968 /**************************************************************************/
_nx_ppp_packet_transmit(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)7969 void  _nx_ppp_packet_transmit(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
7970 {
7971 
7972 NX_PACKET   *current_packet_ptr;
7973 UINT        i;
7974 UCHAR       byte;
7975 UCHAR       *buffer_ptr;
7976 UCHAR       hdlc[3] = {0x7e, 0xff, 0x03};
7977 UCHAR       crc[2];
7978 #ifdef NX_PPP_PPPOE_ENABLE
7979 UINT        release_packet = NX_TRUE;
7980 #endif /* NX_PPP_PPPOE_ENABLE  */
7981 
7982 
7983 #ifdef NX_PPP_DEBUG_LOG_ENABLE
7984 
7985     /* Place the outgoing frame into the optional PPP debug log.  */
7986     _nx_ppp_debug_log_capture(ppp_ptr, 'S', packet_ptr);
7987 #endif
7988 
7989     /* Check for send function.  */
7990     if (ppp_ptr -> nx_ppp_byte_send)
7991     {
7992 
7993         /* Step1. Send the HDLC bytes.  */
7994         for (i = 0; i < 3; i++)
7995         {
7996 
7997             /* Pickup the byte.  */
7998             byte =  hdlc[i];
7999 
8000             /* Determine if it needs an escape sequence.  */
8001             if ((byte < ((UCHAR) 0x20)) || ((byte == ((UCHAR) 0x7e)) && (i != 0)) || (byte == ((UCHAR) 0x7d)))
8002             {
8003 
8004                 /* Yes, this byte needs an escape sequence.  */
8005 
8006                 /* Change the byte.  */
8007                 byte =  byte ^ 0x20;
8008 
8009 #ifndef NX_PPP_DISABLE_INFO
8010 
8011                 /* Increment the number of bytes sent.  */
8012                 ppp_ptr -> nx_ppp_bytes_sent++;
8013 #endif
8014 
8015                 /* Send the escape sequence byte via the user supplied output routine.  */
8016                 ppp_ptr -> nx_ppp_byte_send(0x7d);
8017             }
8018 
8019 #ifndef NX_PPP_DISABLE_INFO
8020 
8021             /* Increment the number of bytes sent.  */
8022             ppp_ptr -> nx_ppp_bytes_sent++;
8023 #endif
8024 
8025             /* Call user supplied byte output routine.  */
8026             ppp_ptr -> nx_ppp_byte_send(byte);
8027         }
8028 
8029         /* Step2. Send the data.  */
8030         /* Initialize the current packet pointer to the packet pointer.  */
8031         current_packet_ptr =  packet_ptr;
8032 
8033         /* Setup the initial buffer pointer.  */
8034         buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
8035 
8036         /* Loop through the buffer to send each byte out.  */
8037         for(i = 0; i < packet_ptr -> nx_packet_length; i++)
8038         {
8039 
8040             /* Determine if we need to move to any additional packets.  */
8041             if (buffer_ptr >= current_packet_ptr -> nx_packet_append_ptr)
8042             {
8043 
8044 #ifndef NX_DISABLE_PACKET_CHAIN
8045 
8046                 /* Yes, we need to move to the next packet.  */
8047                 current_packet_ptr =  current_packet_ptr -> nx_packet_next;
8048 
8049                 /* Determine if there is a next packet.  */
8050                 if (current_packet_ptr == NX_NULL)
8051                 {
8052 
8053 #ifndef NX_PPP_DISABLE_INFO
8054 
8055                     /* Increment the internal error counter.  */
8056                     ppp_ptr -> nx_ppp_internal_errors++;
8057 #endif
8058 
8059                     /* Get out of the loop.  */
8060                     break;
8061                 }
8062 
8063                 /* Otherwise setup new buffer pointer.  */
8064                 buffer_ptr =  current_packet_ptr -> nx_packet_prepend_ptr;
8065 #else
8066                 break;
8067 
8068 #endif /* NX_DISABLE_PACKET_CHAIN */
8069 
8070             }
8071 
8072             /* Pickup the next byte to be sent.  */
8073             byte =  *buffer_ptr++;
8074 
8075             /* Determine if this byte needs an escape sequence.  */
8076             if ((byte < ((UCHAR) 0x20)) || (byte == 0x7e) || (byte == 0x7d))
8077             {
8078 
8079                 /* Yes, this byte needs an escape sequence.  */
8080 
8081                 /* Change the byte.  */
8082                 byte =  byte ^ 0x20;
8083 
8084 #ifndef NX_PPP_DISABLE_INFO
8085 
8086                 /* Increment the number of bytes sent.  */
8087                 ppp_ptr -> nx_ppp_bytes_sent++;
8088 #endif
8089 
8090                 /* Send the escape sequence byte via the user supplied output routine.  */
8091                 ppp_ptr -> nx_ppp_byte_send(0x7d);
8092             }
8093 
8094 #ifndef NX_PPP_DISABLE_INFO
8095 
8096             /* Increment the number of bytes sent.  */
8097             ppp_ptr -> nx_ppp_bytes_sent++;
8098 #endif
8099 
8100             /* Call user supplied byte output routine.  */
8101             ppp_ptr -> nx_ppp_byte_send(byte);
8102         }
8103 
8104         /* Step3. Send CRC.  */
8105         /* Place a CRC at the end of the transmit buffer.  */
8106          _nx_ppp_crc_append(packet_ptr, crc);
8107 
8108         /* Now send the CRC and end-of-frame bytes.  */
8109         for (i = 0; i < 2; i++)
8110         {
8111 
8112             /* Pickup the byte.  */
8113             byte =  crc[i];
8114 
8115             /* Determine if it needs an escape sequence.  */
8116             if ((byte < ((UCHAR) 0x20)) || (byte == ((UCHAR) 0x7e)) || (byte == ((UCHAR) 0x7d)))
8117             {
8118 
8119                 /* Yes, this byte needs an escape sequence.  */
8120 
8121                 /* Change the byte.  */
8122                 byte =  byte ^ 0x20;
8123 
8124 #ifndef NX_PPP_DISABLE_INFO
8125 
8126                 /* Increment the number of bytes sent.  */
8127                 ppp_ptr -> nx_ppp_bytes_sent++;
8128 #endif
8129 
8130                 /* Send the escape sequence byte via the user supplied output routine.  */
8131                 ppp_ptr -> nx_ppp_byte_send(0x7d);
8132             }
8133 
8134 #ifndef NX_PPP_DISABLE_INFO
8135 
8136             /* Increment the number of bytes sent.  */
8137             ppp_ptr -> nx_ppp_bytes_sent++;
8138 #endif
8139 
8140             /* Call user supplied byte output routine.  */
8141             ppp_ptr -> nx_ppp_byte_send(byte);
8142         }
8143 
8144         /* Step4. Finally, send an end-of-frame character.  */
8145         ppp_ptr -> nx_ppp_byte_send((UCHAR) 0x7e);
8146      }
8147 
8148 #ifdef NX_PPP_PPPOE_ENABLE
8149 
8150      /* Check the PPPoE packet send function.  */
8151      if (ppp_ptr -> nx_ppp_packet_send)
8152      {
8153 
8154          /* Send the packet out.  */
8155          (ppp_ptr -> nx_ppp_packet_send)(packet_ptr);
8156 
8157          /* Update the flag since this packet should been released in PPPoE.  */
8158          release_packet = NX_FALSE;
8159 
8160      }
8161 
8162      /* Check if need to release the packet.  */
8163      if (release_packet == NX_TRUE)
8164      {
8165 #endif /* NX_PPP_PPPOE_ENABLE  */
8166 
8167          /* Remove the PPP header.  */
8168          packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
8169          packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
8170 
8171          /* Release the packet.  */
8172          nx_packet_transmit_release(packet_ptr);
8173 
8174 #ifdef NX_PPP_PPPOE_ENABLE
8175      }
8176 #endif /* NX_PPP_PPPOE_ENABLE  */
8177 }
8178 
8179 
8180 /**************************************************************************/
8181 /*                                                                        */
8182 /*  FUNCTION                                               RELEASE        */
8183 /*                                                                        */
8184 /*    _nx_ppp_check_crc                                   PORTABLE C      */
8185 /*                                                           6.1          */
8186 /*  AUTHOR                                                                */
8187 /*                                                                        */
8188 /*    Yuxin Zhou, Microsoft Corporation                                   */
8189 /*                                                                        */
8190 /*  DESCRIPTION                                                           */
8191 /*                                                                        */
8192 /*    This function processes the CRC of the AHDLC packet in the packet   */
8193 /*    payload. If the CRC is correct, the CRC is removed from the receive */
8194 /*    buffer.                                                             */
8195 /*                                                                        */
8196 /*  INPUT                                                                 */
8197 /*                                                                        */
8198 /*    packet_ptr                            Address of PPP instance       */
8199 /*                                                                        */
8200 /*  OUTPUT                                                                */
8201 /*                                                                        */
8202 /*    status                                Completion status             */
8203 /*                                                                        */
8204 /*  CALLS                                                                 */
8205 /*                                                                        */
8206 /*    None                                                                */
8207 /*                                                                        */
8208 /*  CALLED BY                                                             */
8209 /*                                                                        */
8210 /*    _nx_ppp_receive_packet_get            Receive PPP packet processing */
8211 /*                                                                        */
8212 /*  RELEASE HISTORY                                                       */
8213 /*                                                                        */
8214 /*    DATE              NAME                      DESCRIPTION             */
8215 /*                                                                        */
8216 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8217 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8218 /*                                            resulting in version 6.1    */
8219 /*                                                                        */
8220 /**************************************************************************/
_nx_ppp_check_crc(NX_PACKET * packet_ptr)8221 UINT  _nx_ppp_check_crc(NX_PACKET *packet_ptr)
8222 {
8223 
8224 NX_PACKET   *current_packet_ptr;
8225 UCHAR       byte;
8226 UCHAR       *buffer_ptr;
8227 USHORT      i;
8228 USHORT      crc_value;
8229 
8230 
8231     /* Set initial CRC value.  */
8232     crc_value = 0xffff;
8233 
8234     /* Setup buffer pointer.  */
8235     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr + 1;
8236 
8237     /* Setup the current packet pointer.  */
8238     current_packet_ptr =  packet_ptr;
8239 
8240     /* Loop to process the CRC for the receive buffer.  */
8241     for(i = 1; i < (packet_ptr -> nx_packet_length - 1); i++)
8242     {
8243 
8244         /* Determine if the buffer pointer is inside the current packet.  */
8245         if (buffer_ptr >= current_packet_ptr -> nx_packet_append_ptr)
8246         {
8247 
8248 #ifndef NX_DISABLE_PACKET_CHAIN
8249 
8250             /* We have exhausted this packet and must move to the next.  */
8251             current_packet_ptr =  current_packet_ptr -> nx_packet_next;
8252 
8253             /* Determine if there is a next packet.  */
8254             if (current_packet_ptr == NX_NULL)
8255                 break;
8256 
8257             /* Otherwise, we have a valid next packet. Setup the buffer pointer
8258                to the first byte in the next packet.  */
8259             buffer_ptr =  current_packet_ptr -> nx_packet_prepend_ptr;
8260 #else
8261             break;
8262 #endif /* NX_DISABLE_PACKET_CHAIN */
8263 
8264         }
8265 
8266         /* Pickup character from buffer.  */
8267         byte =  *buffer_ptr++;
8268 
8269         /* Update the CRC.  */
8270         crc_value =  (( crc_value >> 8 ) ^ _nx_ppp_crc_table[ ( crc_value & 0xFF ) ^ byte ]);
8271     }
8272 
8273     /* At this point, the CRC should be 0xf0b8.  */
8274     if (crc_value != 0xf0b8)
8275     {
8276 
8277         /* CRC failed, not a valid PPP packet. */
8278        return(NX_PPP_BAD_PACKET);
8279     }
8280 
8281     /* Return successful completion.  */
8282     return(NX_SUCCESS);
8283 }
8284 
8285 
8286 /**************************************************************************/
8287 /*                                                                        */
8288 /*  FUNCTION                                               RELEASE        */
8289 /*                                                                        */
8290 /*    _nx_ppp_crc_append                                  PORTABLE C      */
8291 /*                                                           6.1          */
8292 /*  AUTHOR                                                                */
8293 /*                                                                        */
8294 /*    Yuxin Zhou, Microsoft Corporation                                   */
8295 /*                                                                        */
8296 /*  DESCRIPTION                                                           */
8297 /*                                                                        */
8298 /*    This function calculates and appends the two byte CRC to the        */
8299 /*    frame. It also adds the end of frame marker after the CRC.          */
8300 /*                                                                        */
8301 /*  INPUT                                                                 */
8302 /*                                                                        */
8303 /*    packet_ptr                            Pointer to PPP packet         */
8304 /*    crc                                   Destination for CRC           */
8305 /*                                                                        */
8306 /*  OUTPUT                                                                */
8307 /*                                                                        */
8308 /*    status                                Completion status             */
8309 /*                                                                        */
8310 /*  CALLS                                                                 */
8311 /*                                                                        */
8312 /*    None                                                                */
8313 /*                                                                        */
8314 /*  CALLED BY                                                             */
8315 /*                                                                        */
8316 /*    _nx_ppp_packet_transmit               PPP packet transmit routine   */
8317 /*                                                                        */
8318 /*  RELEASE HISTORY                                                       */
8319 /*                                                                        */
8320 /*    DATE              NAME                      DESCRIPTION             */
8321 /*                                                                        */
8322 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8323 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8324 /*                                            resulting in version 6.1    */
8325 /*                                                                        */
8326 /**************************************************************************/
_nx_ppp_crc_append(NX_PACKET * packet_ptr,UCHAR crc[2])8327 UINT  _nx_ppp_crc_append(NX_PACKET *packet_ptr, UCHAR crc[2])
8328 {
8329 
8330 NX_PACKET   *current_packet_ptr;
8331 UCHAR       *buffer_ptr;
8332 UINT        i;
8333 USHORT      crc_value;
8334 UCHAR       byte;
8335 UCHAR       address = 0xff;
8336 UCHAR       control = 0x03;
8337 
8338 
8339     /* The FCS field is calculated over all bits of the Address, Control,
8340        Protocol, Information and Padding fields, not including any start
8341        and stop bits (asynchronous) nor any bits (synchronous) or octets
8342        (asynchronous or synchronous) inserted for transparency.  This
8343        also does not include the Flag Sequences nor the FCS field itself.
8344        RFC1662, Section3.1, Page6.  */
8345 
8346     /* Initialize CRC value.  */
8347     crc_value = 0xffff;
8348 
8349     /* Step1. Calculate address and control.  */
8350     crc_value = ( crc_value >> 8 ) ^ _nx_ppp_crc_table[ ( crc_value & 0xFF ) ^ address ];
8351     crc_value = ( crc_value >> 8 ) ^ _nx_ppp_crc_table[ ( crc_value & 0xFF ) ^ control ];
8352 
8353     /* Step2. Calculate protocol, information and padding fiedls.  */
8354 
8355     /* Initialize the current packet pointer to the packet pointer.  */
8356     current_packet_ptr =  packet_ptr;
8357 
8358     /* Setup the initial buffer pointer.  */
8359     buffer_ptr =  packet_ptr -> nx_packet_prepend_ptr;
8360 
8361     /* Loop to calculate CRC.  */
8362     for(i = 0; i < packet_ptr -> nx_packet_length; i++)
8363     {
8364 
8365         /* Determine if we need to move to any additional packets.  */
8366         if (buffer_ptr >= current_packet_ptr -> nx_packet_append_ptr)
8367         {
8368 
8369 #ifndef NX_DISABLE_PACKET_CHAIN
8370 
8371             /* Yes, we need to move to the next packet.  */
8372             current_packet_ptr =  current_packet_ptr -> nx_packet_next;
8373 
8374             /* Determine if there is a next packet.  */
8375             if (current_packet_ptr == NX_NULL)
8376             {
8377 
8378                 /* Get out of the loop.  */
8379                 break;
8380             }
8381 
8382             /* Otherwise setup new buffer pointer.  */
8383             buffer_ptr =  current_packet_ptr -> nx_packet_prepend_ptr;
8384 #else
8385             break;
8386 #endif /* NX_DISABLE_PACKET_CHAIN */
8387 
8388         }
8389 
8390         /* Pickup the next byte to be sent.  */
8391         byte =  *buffer_ptr++;
8392 
8393         /* Update the CRC.  */
8394         crc_value = ( crc_value >> 8 ) ^ _nx_ppp_crc_table[ ( crc_value & 0xFF ) ^ byte ];
8395     }
8396 
8397     /* Now complement the CRC value.  */
8398     crc_value = crc_value ^ 0xffff;
8399 
8400     /* Store first byte of the CRC.  */
8401     crc[0] =  (UCHAR) (crc_value & 0xff);
8402 
8403     /* Store second byte of the CRC.  */
8404     crc[1] =  (UCHAR) ((crc_value >> 8) & 0xff);
8405 
8406     /* Return a successful completion.  */
8407     return(NX_SUCCESS);
8408 }
8409 
8410 
8411 #ifdef NX_PPP_DEBUG_LOG_ENABLE
8412 /**************************************************************************/
8413 /*                                                                        */
8414 /*  FUNCTION                                               RELEASE        */
8415 /*                                                                        */
8416 /*    _nx_ppp_debug_log_capture                           PORTABLE C      */
8417 /*                                                           6.1          */
8418 /*  AUTHOR                                                                */
8419 /*                                                                        */
8420 /*    Yuxin Zhou, Microsoft Corporation                                   */
8421 /*                                                                        */
8422 /*  DESCRIPTION                                                           */
8423 /*                                                                        */
8424 /*    This function places the current frame into the circular debug      */
8425 /*    log.                                                                */
8426 /*                                                                        */
8427 /*  INPUT                                                                 */
8428 /*                                                                        */
8429 /*    ppp_ptr                               Pointer to PPP structure      */
8430 /*    packet_type                           Either a send or receive      */
8431 /*    packet_ptr                            Pointer to PPP packet         */
8432 /*                                                                        */
8433 /*  OUTPUT                                                                */
8434 /*                                                                        */
8435 /*    status                                Completion status             */
8436 /*                                                                        */
8437 /*  CALLS                                                                 */
8438 /*                                                                        */
8439 /*    tx_time_get                           Get time                      */
8440 /*                                                                        */
8441 /*  CALLED BY                                                             */
8442 /*                                                                        */
8443 /*    _nx_ppp_packet_transmit               Transmit packet processing    */
8444 /*    _nx_ppp_thread_entry                  Receive thread processing     */
8445 /*                                                                        */
8446 /*  RELEASE HISTORY                                                       */
8447 /*                                                                        */
8448 /*    DATE              NAME                      DESCRIPTION             */
8449 /*                                                                        */
8450 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8451 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8452 /*                                            resulting in version 6.1    */
8453 /*                                                                        */
8454 /**************************************************************************/
_nx_ppp_debug_log_capture(NX_PPP * ppp_ptr,UCHAR packet_type,NX_PACKET * packet_ptr)8455 void  _nx_ppp_debug_log_capture(NX_PPP *ppp_ptr, UCHAR packet_type, NX_PACKET *packet_ptr)
8456 {
8457 
8458 UINT                i;
8459 ULONG               time;
8460 NX_PPP_DEBUG_ENTRY *entry_ptr;
8461 
8462     /* Check for a NULL pointer.  */
8463     if (packet_ptr == NX_NULL)
8464         return;
8465 
8466     /* Pickup current time.  */
8467     time =  tx_time_get();
8468 
8469 #ifdef NX_PPP_DEBUG_LOG_PRINT_ENABLE
8470     /* Print out the current time stamp.  */
8471     printf("Time: %lu, ", time);
8472 
8473     /* Print out the PPP name.  */
8474     printf("PPP Name: %s, ", ppp_ptr -> nx_ppp_name);
8475 
8476     /* Print out the current PPP state.  */
8477     printf("PPP State: %u, ", ppp_ptr -> nx_ppp_state);
8478 
8479     /* Print out the current PPP LCP state.  */
8480     printf("PPP LCP State: %u, ", ppp_ptr -> nx_ppp_lcp_state);
8481 
8482     /* Print out the current PPP PAP state.  */
8483     printf("PPP PAP State: %u, ", ppp_ptr -> nx_ppp_pap_state);
8484 
8485     /* Print out the current PPP CHAP state.  */
8486     printf("PPP CHAP State: %u, ", ppp_ptr -> nx_ppp_chap_state);
8487 
8488     /* Print out the current IPCP state.  */
8489     printf("PPP IPCP State: %u, ", ppp_ptr -> nx_ppp_ipcp_state);
8490 
8491      /* Print out the authentication flag.  */
8492      if (ppp_ptr -> nx_ppp_authenticated)
8493          printf("Authenticated, ");
8494      else
8495          printf("Not Authenticated, ");
8496 
8497      /* Determine if the packet is a receive packet or a send packet.  */
8498      if (packet_type == 'R')
8499          printf("Received Packet Length: %lu, Packet: ", packet_ptr -> nx_packet_length);
8500      else
8501          printf("Send Packet Length: %lu, Packet: ", packet_ptr -> nx_packet_length);
8502 
8503     /* Dump out at least part of the packet payload.  */
8504     for (i = 0; i < packet_ptr -> nx_packet_length; i++)
8505     {
8506 
8507         /* Check for packet spanning multiple packets.  */
8508         if ((packet_ptr -> nx_packet_prepend_ptr+i) >= packet_ptr -> nx_packet_append_ptr)
8509             break;
8510 
8511         /* Check for maximum dump size.  */
8512         if (i >= NX_PPP_DEBUG_FRAME_SIZE)
8513             break;
8514 
8515         /* Print one character.  */
8516         printf("%02x ", packet_ptr -> nx_packet_prepend_ptr[i]);
8517     }
8518 
8519     printf("\n");
8520 #endif /* NX_PPP_DEBUG_LOG_PRINT_ENABLE */
8521 
8522     /* Now load the internal PPP log.  */
8523 
8524     /* Setup the debug log entry pointer.  */
8525     entry_ptr =  &(ppp_ptr -> nx_ppp_debug_log[ppp_ptr -> nx_ppp_debug_log_oldest_index++]);
8526 
8527     /* Check for wrap-around of the index.  */
8528     if (ppp_ptr -> nx_ppp_debug_log_oldest_index >= NX_PPP_DEBUG_LOG_SIZE)
8529         ppp_ptr -> nx_ppp_debug_log_oldest_index =  0;
8530 
8531     /* Setup the debug log entries.  */
8532     entry_ptr -> nx_ppp_debug_entry_time_stamp =  time;
8533     entry_ptr -> nx_ppp_debug_ppp_state =         (UCHAR) ppp_ptr -> nx_ppp_state;
8534     entry_ptr -> nx_ppp_debug_lcp_state =         (UCHAR) ppp_ptr -> nx_ppp_lcp_state;
8535     entry_ptr -> nx_ppp_debug_pap_state =         (UCHAR) ppp_ptr -> nx_ppp_pap_state;
8536     entry_ptr -> nx_ppp_debug_chap_state =        (UCHAR) ppp_ptr -> nx_ppp_chap_state;
8537     entry_ptr -> nx_ppp_debug_ipcp_state =        (UCHAR) ppp_ptr -> nx_ppp_ipcp_state;
8538     entry_ptr -> nx_ppp_debug_authenticated =     ppp_ptr -> nx_ppp_authenticated;
8539     entry_ptr -> nx_ppp_debug_frame_type =        packet_type;
8540     entry_ptr -> nx_ppp_debug_packet_length =     packet_ptr -> nx_packet_length;
8541 
8542     /* Store at least part of the packet payload.  */
8543     for (i = 0; i < packet_ptr -> nx_packet_length; i++)
8544     {
8545 
8546         /* Check for packet spanning multiple packets.  */
8547         if ((packet_ptr -> nx_packet_prepend_ptr+i) >= packet_ptr -> nx_packet_append_ptr)
8548             break;
8549 
8550         /* Check for maximum dump size.  */
8551         if (i >= NX_PPP_DEBUG_FRAME_SIZE)
8552             break;
8553 
8554         /* Store one character.  */
8555         entry_ptr -> nx_ppp_debug_frame[i] =  packet_ptr -> nx_packet_prepend_ptr[i];
8556     }
8557 }
8558 
8559 
8560 /**************************************************************************/
8561 /*                                                                        */
8562 /*  FUNCTION                                               RELEASE        */
8563 /*                                                                        */
8564 /*    _nx_ppp_debug_log_capture_protocol                  PORTABLE C      */
8565 /*                                                           6.1          */
8566 /*  AUTHOR                                                                */
8567 /*                                                                        */
8568 /*    Yuxin Zhou, Microsoft Corporation                                   */
8569 /*                                                                        */
8570 /*  DESCRIPTION                                                           */
8571 /*                                                                        */
8572 /*    This function outputs the status of various protocols and timeouts  */
8573 /*    of the specified PPP instance.                                      */
8574 /*                                                                        */
8575 /*  INPUT                                                                 */
8576 /*                                                                        */
8577 /*    ppp_ptr                               Pointer to PPP structure      */
8578 /*                                                                        */
8579 /*  OUTPUT                                                                */
8580 /*                                                                        */
8581 /*    status                                Completion status             */
8582 /*                                                                        */
8583 /*  CALLS                                                                 */
8584 /*                                                                        */
8585 /*                                                                        */
8586 /*  CALLED BY                                                             */
8587 /*                                                                        */
8588 /*    _nx_ppp_thread_entry                  PPP event processing          */
8589 /*                                                                        */
8590 /*  RELEASE HISTORY                                                       */
8591 /*                                                                        */
8592 /*    DATE              NAME                      DESCRIPTION             */
8593 /*                                                                        */
8594 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8595 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8596 /*                                            resulting in version 6.1    */
8597 /*                                                                        */
8598 /**************************************************************************/
_nx_ppp_debug_log_capture_protocol(NX_PPP * ppp_ptr)8599 void  _nx_ppp_debug_log_capture_protocol(NX_PPP *ppp_ptr)
8600 {
8601 
8602 
8603     /* Print out the PPP name.  */
8604     printf("%s: ", ppp_ptr -> nx_ppp_name);
8605 
8606     /* Print out the current PPP state.  */
8607     printf("State: %u, ", ppp_ptr -> nx_ppp_state);
8608 
8609     /* Print out the current PPP LCP state.  */
8610     printf("LCP State: %u, ", ppp_ptr -> nx_ppp_lcp_state);
8611 
8612     /* Print out the current IPCP state.  */
8613     printf("IPCP State: %u, ", ppp_ptr -> nx_ppp_ipcp_state);
8614 
8615     if ((ppp_ptr -> nx_ppp_chap_enabled) || (ppp_ptr -> nx_ppp_pap_enabled))
8616     {
8617 
8618          /* Print out the authentication flag.  */
8619          if (ppp_ptr -> nx_ppp_authenticated)
8620              printf("Authenticated, ");
8621          else
8622          {
8623 
8624              printf("Not Authenticated, ");
8625 
8626              /* Print out the current PPP PAP state.  */
8627              printf("PAP State: %u, ", ppp_ptr -> nx_ppp_pap_state);
8628 
8629              /* Print out the current PPP CHAP state.  */
8630              printf("CHAP State: %u, ", ppp_ptr -> nx_ppp_chap_state);
8631          }
8632     }
8633 
8634     /* Print out the current PPP LCP state.  */
8635     printf("Time remaining: %lu, ", ppp_ptr -> nx_ppp_timeout);
8636     printf("Timeouts: %lu, ", ppp_ptr -> nx_ppp_receive_timeouts);
8637     printf("Protocol retries: %lu, ", ppp_ptr -> nx_ppp_protocol_retry_counter);
8638 
8639     printf("\n");
8640 }
8641 #endif /* NX_PPP_DEBUG_LOG_ENABLE */
8642 
8643 
8644 #ifndef NX_PPP_DISABLE_CHAP
8645 /**************************************************************************/
8646 /*                                                                        */
8647 /*  FUNCTION                                               RELEASE        */
8648 /*                                                                        */
8649 /*    _nx_ppp_hash_generator                              PORTABLE C      */
8650 /*                                                           6.1          */
8651 /*  AUTHOR                                                                */
8652 /*                                                                        */
8653 /*    Yuxin Zhou, Microsoft Corporation                                   */
8654 /*                                                                        */
8655 /*  DESCRIPTION                                                           */
8656 /*                                                                        */
8657 /*    This function calculates the MD5 hash value for CHAP authentication */
8658 /*    processing.  The input challenge "rand_value" is a stream of octets,*/
8659 /*    including 0x0, so the length option ensures the rand_value length is*/
8660 /*    set correctly.                                                      */
8661 /*                                                                        */
8662 /*    If the caller is certain there is no 0x0 within the rand_value it   */
8663 /*    can send a zero length arguement and this function will compute the */
8664 /*    rand_value length.                                                  */
8665 /*                                                                        */
8666 /*  INPUT                                                                 */
8667 /*                                                                        */
8668 /*    hvalue                                Hash value return string      */
8669 /*    id                                    PPP message ID                */
8670 /*    secret                                Secret input string           */
8671 /*    rand_value                            Random value input string     */
8672 /*    length                                Length of random string,      */
8673 /*                                           if zero, assume null         */
8674 /*                                           terminated                   */
8675 /*                                                                        */
8676 /*  OUTPUT                                                                */
8677 /*                                                                        */
8678 /*    None                                                                */
8679 /*                                                                        */
8680 /*  CALLS                                                                 */
8681 /*                                                                        */
8682 /*    None                                                                */
8683 /*                                                                        */
8684 /*  CALLED BY                                                             */
8685 /*                                                                        */
8686 /*    _nx_ppp_chap_challenge_respond        CHAP challenge response       */
8687 /*    _nx_ppp_chap_challenge_validate       CHAP validate response        */
8688 /*                                                                        */
8689 /*  RELEASE HISTORY                                                       */
8690 /*                                                                        */
8691 /*    DATE              NAME                      DESCRIPTION             */
8692 /*                                                                        */
8693 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8694 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8695 /*                                            resulting in version 6.1    */
8696 /*                                                                        */
8697 /**************************************************************************/
_nx_ppp_hash_generator(unsigned char * hvalue,unsigned char id,unsigned char * secret,unsigned char * rand_value,UINT length)8698 void _nx_ppp_hash_generator(unsigned char *hvalue,  unsigned char id,
8699                             unsigned char *secret,  unsigned char *rand_value, UINT length)
8700 {
8701 
8702 UINT    slen, rlen;
8703 NX_MD5  context;
8704 
8705 
8706     /* Compute the length of the secret. */
8707     for(slen = 0; secret[slen]; slen++);
8708 
8709     /* Compute the length of the rand_value if no length is specified. */
8710     if(length==0)
8711     {
8712         for(rlen = 0; rand_value[rlen]; rlen++);
8713     }
8714     else
8715     {
8716         rlen = length;
8717     }
8718 
8719     /* Initialize the MD5 digest calculation.  */
8720     _nx_md5_initialize(&context);
8721 
8722     /* Update the digest.  */
8723     _nx_md5_update(&context, &id, 1);
8724     _nx_md5_update(&context, secret, slen);
8725     _nx_md5_update(&context, rand_value, rlen);
8726 
8727     /* Finally, calculate the digest.  */
8728     _nx_md5_digest_calculate(&context, hvalue);
8729 }
8730 #endif /* NX_PPP_DISABLE_CHAP */
8731 
8732 
8733 /* Define externally available API functions.  */
8734 
8735 
8736 /**************************************************************************/
8737 /*                                                                        */
8738 /*  FUNCTION                                               RELEASE        */
8739 /*                                                                        */
8740 /*    _nxe_ppp_byte_receive                               PORTABLE C      */
8741 /*                                                           6.1          */
8742 /*  AUTHOR                                                                */
8743 /*                                                                        */
8744 /*    Yuxin Zhou, Microsoft Corporation                                   */
8745 /*                                                                        */
8746 /*  DESCRIPTION                                                           */
8747 /*                                                                        */
8748 /*    This function checks for errors in the PPP byte receive             */
8749 /*    function call.                                                      */
8750 /*                                                                        */
8751 /*  INPUT                                                                 */
8752 /*                                                                        */
8753 /*    ppp_ptr                               Pointer to PPP instance       */
8754 /*    byte                                  Newly received byte           */
8755 /*                                                                        */
8756 /*  OUTPUT                                                                */
8757 /*                                                                        */
8758 /*    status                                Completion status             */
8759 /*                                                                        */
8760 /*  CALLS                                                                 */
8761 /*                                                                        */
8762 /*    _nx_ppp_byte_receive                  Actual PPP byte receive       */
8763 /*                                            function                    */
8764 /*                                                                        */
8765 /*  CALLED BY                                                             */
8766 /*                                                                        */
8767 /*    Application Code                                                    */
8768 /*                                                                        */
8769 /*  RELEASE HISTORY                                                       */
8770 /*                                                                        */
8771 /*    DATE              NAME                      DESCRIPTION             */
8772 /*                                                                        */
8773 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8774 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8775 /*                                            resulting in version 6.1    */
8776 /*                                                                        */
8777 /**************************************************************************/
_nxe_ppp_byte_receive(NX_PPP * ppp_ptr,UCHAR byte)8778 UINT  _nxe_ppp_byte_receive(NX_PPP *ppp_ptr, UCHAR byte)
8779 {
8780 
8781 UINT    status;
8782 
8783 
8784     /* Check for an invalid input pointer.  */
8785     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
8786         return(NX_PTR_ERROR);
8787 
8788     /* Call actual byte receive function.  */
8789     status =  _nx_ppp_byte_receive(ppp_ptr, byte);
8790 
8791     /* Return completion status.  */
8792     return(status);
8793 }
8794 
8795 
8796 /**************************************************************************/
8797 /*                                                                        */
8798 /*  FUNCTION                                               RELEASE        */
8799 /*                                                                        */
8800 /*    _nx_ppp_byte_receive                                PORTABLE C      */
8801 /*                                                           6.1          */
8802 /*  AUTHOR                                                                */
8803 /*                                                                        */
8804 /*    Yuxin Zhou, Microsoft Corporation                                   */
8805 /*                                                                        */
8806 /*  DESCRIPTION                                                           */
8807 /*                                                                        */
8808 /*    This function receives a byte from the application (usually an      */
8809 /*    application ISR), buffers it, and notifies the PPP receive thread.  */
8810 /*                                                                        */
8811 /*  INPUT                                                                 */
8812 /*                                                                        */
8813 /*    ppp_ptr                               Pointer to PPP instance       */
8814 /*    byte                                  Newly received byte           */
8815 /*                                                                        */
8816 /*  OUTPUT                                                                */
8817 /*                                                                        */
8818 /*    status                                Completion status             */
8819 /*                                                                        */
8820 /*  CALLS                                                                 */
8821 /*                                                                        */
8822 /*    tx_event_flags_set                    Notify PPP receiving thread   */
8823 /*                                                                        */
8824 /*  CALLED BY                                                             */
8825 /*                                                                        */
8826 /*    Application Code (Including ISRs)                                   */
8827 /*                                                                        */
8828 /*  RELEASE HISTORY                                                       */
8829 /*                                                                        */
8830 /*    DATE              NAME                      DESCRIPTION             */
8831 /*                                                                        */
8832 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8833 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8834 /*                                            resulting in version 6.1    */
8835 /*                                                                        */
8836 /**************************************************************************/
_nx_ppp_byte_receive(NX_PPP * ppp_ptr,UCHAR byte)8837 UINT  _nx_ppp_byte_receive(NX_PPP *ppp_ptr, UCHAR byte)
8838 {
8839 
8840 TX_INTERRUPT_SAVE_AREA
8841 
8842 
8843     /* Disable interrupts.  */
8844     TX_DISABLE
8845 
8846     /* Check for no longer active PPP instance.  */
8847     if (ppp_ptr -> nx_ppp_id != NX_PPP_ID)
8848     {
8849 
8850         /* PPP is no longer active.  */
8851 
8852         /* Restore interrupts.  */
8853         TX_RESTORE
8854 
8855         /* Return an error.  */
8856         return(NX_PTR_ERROR);
8857     }
8858 
8859     /* Check for a stopped PPP instance.  */
8860     if (ppp_ptr -> nx_ppp_state == NX_PPP_STOPPED)
8861     {
8862 
8863         /* Silently discard byte.  */
8864 
8865         /* Restore interrupts.  */
8866         TX_RESTORE
8867 
8868         /* Return success.  */
8869         return(NX_SUCCESS);
8870     }
8871 
8872     /* Determine if there is enough room in the serial buffer.  */
8873     if (ppp_ptr -> nx_ppp_serial_buffer_byte_count >= NX_PPP_SERIAL_BUFFER_SIZE)
8874     {
8875 
8876 #ifndef NX_PPP_DISABLE_INFO
8877         /* Increment the number of bytes dropped.  */
8878         ppp_ptr -> nx_ppp_bytes_dropped++;
8879 #endif
8880 
8881         /* Restore interrupts.  */
8882         TX_RESTORE
8883 
8884         /* No, return an error.  */
8885         return(NX_PPP_BUFFER_FULL);
8886     }
8887 
8888     /* Otherwise, PPP is active and there is room in the buffer!  */
8889 
8890     /* Place the byte in the buffer.  */
8891     ppp_ptr -> nx_ppp_serial_buffer[ppp_ptr -> nx_ppp_serial_buffer_write_index++] =  byte;
8892 
8893     /* Check for a wrap-around of the serial buffer.  */
8894     if (ppp_ptr -> nx_ppp_serial_buffer_write_index >= NX_PPP_SERIAL_BUFFER_SIZE)
8895     {
8896 
8897         /* Yes, buffer wrap-around is present. Reset the write pointer to the beginning of the
8898            buffer.  */
8899         ppp_ptr -> nx_ppp_serial_buffer_write_index =  0;
8900     }
8901 
8902     /* Increment the byte count.  */
8903     ppp_ptr -> nx_ppp_serial_buffer_byte_count++;
8904 
8905 #ifndef NX_PPP_DISABLE_INFO
8906     /* Increment the number of bytes received.  */
8907     ppp_ptr -> nx_ppp_bytes_received++;
8908 #endif
8909 
8910     /* Restore interrupts.  */
8911     TX_RESTORE
8912 
8913     /* Determine if the PPP receive thread needs to be alerted.  */
8914     if ((ppp_ptr -> nx_ppp_serial_buffer_byte_count >= NX_PPP_SERIAL_BUFFER_ALERT_THRESHOLD) ||
8915         (byte == 0x7e))
8916     {
8917 
8918         /* Yes, alert the receiving thread that a byte is available for processing.  */
8919         tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_PACKET_RECEIVE, TX_OR);
8920     }
8921 
8922     /* Return successful completion.  */
8923     return(NX_SUCCESS);
8924 }
8925 
8926 
8927 /**************************************************************************/
8928 /*                                                                        */
8929 /*  FUNCTION                                               RELEASE        */
8930 /*                                                                        */
8931 /*    _nxe_ppp_create                                     PORTABLE C      */
8932 /*                                                           6.1          */
8933 /*  AUTHOR                                                                */
8934 /*                                                                        */
8935 /*    Yuxin Zhou, Microsoft Corporation                                   */
8936 /*                                                                        */
8937 /*  DESCRIPTION                                                           */
8938 /*                                                                        */
8939 /*    This function checks for errors in the PPP create instance          */
8940 /*    function call.                                                      */
8941 /*                                                                        */
8942 /*  INPUT                                                                 */
8943 /*                                                                        */
8944 /*    ppp_ptr                               Pointer to instance           */
8945 /*    name                                  Pointer to instance name      */
8946 /*    ip_ptr                                Pointer to IP instance        */
8947 /*    stack_memory_ptr                      Pointer to thread stack       */
8948 /*    stack_size                            Pointer to thread stack size  */
8949 /*    thread_priority                       Priority of thread(s) created */
8950 /*                                            for PPP                     */
8951 /*    pool_ptr                              Default packet pool pointer   */
8952 /*    ppp_non_ppp_packet_handler            Non PPP packet handler        */
8953 /*                                            provided by the application */
8954 /*    ppp_byte_send                         Byte output function provided */
8955 /*                                            by the application          */
8956 /*                                                                        */
8957 /*  OUTPUT                                                                */
8958 /*                                                                        */
8959 /*    status                                Completion status             */
8960 /*                                                                        */
8961 /*  CALLS                                                                 */
8962 /*                                                                        */
8963 /*    _nx_ppp_create                        Actual PPP create function    */
8964 /*                                                                        */
8965 /*  CALLED BY                                                             */
8966 /*                                                                        */
8967 /*    Application Code                                                    */
8968 /*                                                                        */
8969 /*  RELEASE HISTORY                                                       */
8970 /*                                                                        */
8971 /*    DATE              NAME                      DESCRIPTION             */
8972 /*                                                                        */
8973 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
8974 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
8975 /*                                            resulting in version 6.1    */
8976 /*                                                                        */
8977 /**************************************************************************/
_nxe_ppp_create(NX_PPP * ppp_ptr,CHAR * name,NX_IP * ip_ptr,VOID * stack_memory_ptr,ULONG stack_size,UINT thread_priority,NX_PACKET_POOL * pool_ptr,void (* ppp_non_ppp_packet_handler)(NX_PACKET * packet_ptr),void (* ppp_byte_send)(UCHAR byte))8978 UINT  _nxe_ppp_create(NX_PPP *ppp_ptr, CHAR *name, NX_IP *ip_ptr,
8979                VOID *stack_memory_ptr, ULONG stack_size, UINT thread_priority,
8980                NX_PACKET_POOL *pool_ptr,
8981                void (*ppp_non_ppp_packet_handler)(NX_PACKET *packet_ptr),
8982                void (*ppp_byte_send)(UCHAR byte))
8983 {
8984 
8985 UINT    status;
8986 
8987 
8988     /* Check for an invalid input pointer.  */
8989     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id == NX_PPP_ID) ||
8990         (ip_ptr == NX_NULL) || (stack_memory_ptr == NX_NULL) || (pool_ptr == NX_NULL))
8991         return(NX_PTR_ERROR);
8992 
8993     /* Check for valid caller.  */
8994     NX_INIT_AND_THREADS_CALLER_CHECKING
8995 
8996     /* Call actual PPP create function.  */
8997     status =  _nx_ppp_create(ppp_ptr, name, ip_ptr, stack_memory_ptr, stack_size, thread_priority,
8998                                 pool_ptr, ppp_non_ppp_packet_handler, ppp_byte_send);
8999 
9000     /* Return completion status.  */
9001     return(status);
9002 }
9003 
9004 
9005 /**************************************************************************/
9006 /*                                                                        */
9007 /*  FUNCTION                                               RELEASE        */
9008 /*                                                                        */
9009 /*    _nx_ppp_create                                      PORTABLE C      */
9010 /*                                                           6.1          */
9011 /*  AUTHOR                                                                */
9012 /*                                                                        */
9013 /*    Yuxin Zhou, Microsoft Corporation                                   */
9014 /*                                                                        */
9015 /*  DESCRIPTION                                                           */
9016 /*                                                                        */
9017 /*    This function creates a PPP instance for the specified IP.          */
9018 /*                                                                        */
9019 /*  INPUT                                                                 */
9020 /*                                                                        */
9021 /*    ppp_ptr                               Pointer to instance           */
9022 /*    name                                  Pointer to instance name      */
9023 /*    ip_ptr                                Pointer to IP instance        */
9024 /*    stack_memory_ptr                      Pointer to thread stack       */
9025 /*    stack_size                            Pointer to thread stack size  */
9026 /*    thread_priority                       Priority of thread(s) created */
9027 /*                                            for PPP                     */
9028 /*    pool_ptr                              Default packet pool pointer   */
9029 /*    ppp_non_ppp_packet_handler            Non PPP packet handler        */
9030 /*                                            provided by the application */
9031 /*    ppp_byte_send                         Byte output function provided */
9032 /*                                            by the application          */
9033 /*                                                                        */
9034 /*  OUTPUT                                                                */
9035 /*                                                                        */
9036 /*    status                                Completion status             */
9037 /*                                                                        */
9038 /*  CALLS                                                                 */
9039 /*                                                                        */
9040 /*    tx_event_flags_create                 Create PPP event flags group  */
9041 /*    tx_thread_create                      Create PPP helper thread      */
9042 /*    tx_time_get                           Get time for IDs              */
9043 /*    tx_timer_create                       Create PPP timer              */
9044 /*                                                                        */
9045 /*  CALLED BY                                                             */
9046 /*                                                                        */
9047 /*    Application Code                                                    */
9048 /*                                                                        */
9049 /*  RELEASE HISTORY                                                       */
9050 /*                                                                        */
9051 /*    DATE              NAME                      DESCRIPTION             */
9052 /*                                                                        */
9053 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9054 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9055 /*                                            resulting in version 6.1    */
9056 /*                                                                        */
9057 /**************************************************************************/
_nx_ppp_create(NX_PPP * ppp_ptr,CHAR * name,NX_IP * ip_ptr,VOID * stack_memory_ptr,ULONG stack_size,UINT thread_priority,NX_PACKET_POOL * pool_ptr,void (* ppp_non_ppp_packet_handler)(NX_PACKET * packet_ptr),void (* ppp_byte_send)(UCHAR byte))9058 UINT  _nx_ppp_create(NX_PPP *ppp_ptr, CHAR *name, NX_IP *ip_ptr,
9059                VOID *stack_memory_ptr, ULONG stack_size, UINT thread_priority,
9060                NX_PACKET_POOL *pool_ptr,
9061                void (*ppp_non_ppp_packet_handler)(NX_PACKET *packet_ptr),
9062                void (*ppp_byte_send)(UCHAR byte))
9063 {
9064 
9065 TX_INTERRUPT_SAVE_AREA
9066 
9067 NX_PPP      *tail_ptr;
9068 
9069 
9070     /* Check the supplied packet pool for minimum required payload length.  */
9071     if (pool_ptr -> nx_packet_pool_payload_size < NX_PPP_MIN_PACKET_PAYLOAD)
9072     {
9073         return(NX_PPP_BAD_PACKET);
9074     }
9075 
9076     /* Initialize the PPP control block to zero.  */
9077     memset((void *) ppp_ptr, 0, sizeof(NX_PPP));
9078 
9079     /* Save the PPP name.  */
9080     ppp_ptr -> nx_ppp_name =                    name;
9081 
9082     /* Save the IP pointer.  */
9083     ppp_ptr -> nx_ppp_ip_ptr =                  ip_ptr;
9084 
9085     /* Save the packet pool pointer.  */
9086     ppp_ptr -> nx_ppp_packet_pool_ptr =         pool_ptr;
9087 
9088     /* Save the byte output routine specified by the user.  */
9089     ppp_ptr -> nx_ppp_byte_send =               ppp_byte_send;
9090     ppp_ptr -> nx_ppp_non_ppp_packet_handler =  ppp_non_ppp_packet_handler;
9091 
9092     /* Setup the initial state.  */
9093     ppp_ptr -> nx_ppp_state =                   NX_PPP_STOPPED;
9094 
9095     /* Setup the Maximum Receive Unit (MRU).  */
9096     ppp_ptr -> nx_ppp_mru =                     NX_PPP_MRU;
9097 
9098     /* Setup receive and transmit IDs.  */
9099     ppp_ptr -> nx_ppp_transmit_id =             (UCHAR) tx_time_get();
9100 
9101     /* Default the authenticated field to true.  */
9102     ppp_ptr -> nx_ppp_authenticated =           NX_TRUE;
9103 
9104     /* Create event flag group to control the PPP processing thread.  */
9105     tx_event_flags_create(&(ppp_ptr -> nx_ppp_event), "PPP EVENTS") ;
9106 
9107     /* Create the PPP processing thread. Note that this thread does not run until the PPP driver is
9108        initialized during the IP create.  */
9109     tx_thread_create(&(ppp_ptr -> nx_ppp_thread), "PPP THREAD", _nx_ppp_thread_entry, (ULONG) ppp_ptr,
9110             stack_memory_ptr, stack_size, thread_priority, thread_priority, NX_PPP_THREAD_TIME_SLICE, TX_DONT_START);
9111 
9112     /* Create the PPP timeout timer.  */
9113     tx_timer_create(&(ppp_ptr -> nx_ppp_timer), "PPP TIMER", _nx_ppp_timer_entry, (ULONG) ppp_ptr, NX_PPP_BASE_TIMEOUT, NX_PPP_BASE_TIMEOUT, TX_NO_ACTIVATE);
9114 
9115     /* Otherwise, the PPP initialization was successful.  Place the
9116        PPP control block on the list of created PPP instances.  */
9117     TX_DISABLE
9118 
9119     /* Load the PPP ID field in the PPP control block.  */
9120     ppp_ptr -> nx_ppp_id =  NX_PPP_ID;
9121 
9122     /* Place the new PPP control block on the list of created IPs.  First,
9123        check for an empty list.  */
9124     if (_nx_ppp_created_ptr)
9125     {
9126 
9127         /* Pickup tail pointer.  */
9128         tail_ptr =  _nx_ppp_created_ptr -> nx_ppp_created_previous;
9129 
9130         /* Place the new PPP control block in the list.  */
9131         _nx_ppp_created_ptr -> nx_ppp_created_previous =  ppp_ptr;
9132         tail_ptr -> nx_ppp_created_next =  ppp_ptr;
9133 
9134         /* Setup this PPP's created links.  */
9135         ppp_ptr -> nx_ppp_created_previous =  tail_ptr;
9136         ppp_ptr -> nx_ppp_created_next =      _nx_ppp_created_ptr;
9137     }
9138     else
9139     {
9140 
9141         /* The created PPP list is empty.  Add PPP control block to empty list.  */
9142         _nx_ppp_created_ptr =                ppp_ptr;
9143         ppp_ptr -> nx_ppp_created_next =     ppp_ptr;
9144         ppp_ptr -> nx_ppp_created_previous = ppp_ptr;
9145     }
9146 
9147     /* Increment the created PPP counter.  */
9148     _nx_ppp_created_count++;
9149 
9150     /* Restore previous interrupt posture.  */
9151     TX_RESTORE
9152 
9153     /* Return success.  */
9154     return(NX_SUCCESS);
9155 }
9156 
9157 
9158 /**************************************************************************/
9159 /*                                                                        */
9160 /*  FUNCTION                                               RELEASE        */
9161 /*                                                                        */
9162 /*    _nxe_ppp_delete                                     PORTABLE C      */
9163 /*                                                           6.1          */
9164 /*  AUTHOR                                                                */
9165 /*                                                                        */
9166 /*    Yuxin Zhou, Microsoft Corporation                                   */
9167 /*                                                                        */
9168 /*  DESCRIPTION                                                           */
9169 /*                                                                        */
9170 /*    This function checks for errors in the PPP delete instance          */
9171 /*    function call.                                                      */
9172 /*                                                                        */
9173 /*  INPUT                                                                 */
9174 /*                                                                        */
9175 /*    ppp_ptr                               Pointer to instance           */
9176 /*                                                                        */
9177 /*  OUTPUT                                                                */
9178 /*                                                                        */
9179 /*    status                                Completion status             */
9180 /*                                                                        */
9181 /*  CALLS                                                                 */
9182 /*                                                                        */
9183 /*    _nx_ppp_delete                        Actual PPP delete function    */
9184 /*                                                                        */
9185 /*  CALLED BY                                                             */
9186 /*                                                                        */
9187 /*    Application Code                                                    */
9188 /*                                                                        */
9189 /*  RELEASE HISTORY                                                       */
9190 /*                                                                        */
9191 /*    DATE              NAME                      DESCRIPTION             */
9192 /*                                                                        */
9193 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9194 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9195 /*                                            resulting in version 6.1    */
9196 /*                                                                        */
9197 /**************************************************************************/
_nxe_ppp_delete(NX_PPP * ppp_ptr)9198 UINT  _nxe_ppp_delete(NX_PPP *ppp_ptr)
9199 {
9200 
9201 UINT    status;
9202 
9203 
9204     /* Check for an invalid input pointer.  */
9205     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
9206         return(NX_PTR_ERROR);
9207 
9208     /* Check for valid caller.  */
9209     NX_THREADS_ONLY_CALLER_CHECKING
9210 
9211     /* Call actual PPP delete function.  */
9212     status =  _nx_ppp_delete(ppp_ptr);
9213 
9214     /* Return completion status.  */
9215     return(status);
9216 }
9217 
9218 
9219 /**************************************************************************/
9220 /*                                                                        */
9221 /*  FUNCTION                                               RELEASE        */
9222 /*                                                                        */
9223 /*    _nx_ppp_delete                                      PORTABLE C      */
9224 /*                                                           6.1          */
9225 /*  AUTHOR                                                                */
9226 /*                                                                        */
9227 /*    Yuxin Zhou, Microsoft Corporation                                   */
9228 /*                                                                        */
9229 /*  DESCRIPTION                                                           */
9230 /*                                                                        */
9231 /*    This function deletes a PPP instance for the specified IP.          */
9232 /*                                                                        */
9233 /*  INPUT                                                                 */
9234 /*                                                                        */
9235 /*    ppp_ptr                               Pointer to instance           */
9236 /*                                                                        */
9237 /*  OUTPUT                                                                */
9238 /*                                                                        */
9239 /*    status                                Completion status             */
9240 /*                                                                        */
9241 /*  CALLS                                                                 */
9242 /*                                                                        */
9243 /*    tx_event_flags_delete                 Delete PPP event flags group  */
9244 /*    tx_event_flags_set                    Set PPP event flag to stop PPP*/
9245 /*    tx_thread_delete                      Create PPP helper threads     */
9246 /*    tx_thread_identify                    Identify current thread       */
9247 /*    tx_thread_sleep                       Sleep for a small time        */
9248 /*    tx_timer_deactivate                   Timer deactivate              */
9249 /*    tx_timer_delete                       Delete timer                  */
9250 /*                                                                        */
9251 /*  CALLED BY                                                             */
9252 /*                                                                        */
9253 /*    Application Code                                                    */
9254 /*                                                                        */
9255 /*  RELEASE HISTORY                                                       */
9256 /*                                                                        */
9257 /*    DATE              NAME                      DESCRIPTION             */
9258 /*                                                                        */
9259 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9260 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9261 /*                                            resulting in version 6.1    */
9262 /*                                                                        */
9263 /**************************************************************************/
_nx_ppp_delete(NX_PPP * ppp_ptr)9264 UINT  _nx_ppp_delete(NX_PPP *ppp_ptr)
9265 {
9266 
9267 TX_INTERRUPT_SAVE_AREA
9268 
9269 
9270     /* Determine if the caller is the PPP thread itself. This is not allowed since
9271        a thread cannot delete itself in ThreadX.  */
9272     if (&ppp_ptr -> nx_ppp_thread == tx_thread_identify())
9273     {
9274 
9275         /* Invalid caller of this routine, return an error!  */
9276         return(NX_CALLER_ERROR);
9277     }
9278 
9279     /* Set the event to close the PPP thread.  */
9280     tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
9281 
9282     /* Now wait until the PPP thread goes to a closed state before proceeding with the delete.
9283        This will give PPP the opportunity to properly release all packets being worked on.  */
9284     while (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED)
9285     {
9286 
9287         /* Sleep for a tick.  */
9288         tx_thread_sleep(1);
9289     }
9290 
9291     /* Disable interrupts.  */
9292     TX_DISABLE
9293 
9294     /* Clear the PPP ID to show that it is no longer valid.  */
9295     ppp_ptr -> nx_ppp_id =  0;
9296 
9297     /* Decrement the number of PPP instances created.  */
9298     _nx_ppp_created_count--;
9299 
9300     /* See if the PPP instance is the only one on the list.  */
9301     if (ppp_ptr == ppp_ptr -> nx_ppp_created_next)
9302     {
9303 
9304         /* Only created PPP instance, just set the created list to NULL.  */
9305         _nx_ppp_created_ptr =  TX_NULL;
9306     }
9307     else
9308     {
9309 
9310         /* Link-up the neighbors.  */
9311         (ppp_ptr -> nx_ppp_created_next) -> nx_ppp_created_previous =
9312                                             ppp_ptr -> nx_ppp_created_previous;
9313         (ppp_ptr -> nx_ppp_created_previous) -> nx_ppp_created_next =
9314                                             ppp_ptr -> nx_ppp_created_next;
9315 
9316         /* See if we have to update the created list head pointer.  */
9317         if (_nx_ppp_created_ptr == ppp_ptr)
9318 
9319             /* Yes, move the head pointer to the next link. */
9320             _nx_ppp_created_ptr =  ppp_ptr -> nx_ppp_created_next;
9321     }
9322 
9323     /* Restore previous interrupt posture.  */
9324     TX_RESTORE
9325 
9326     /* Terminate the thread.  */
9327     tx_thread_terminate(&(ppp_ptr -> nx_ppp_thread));
9328 
9329     /* Delete the PPP thread.  */
9330     tx_thread_delete(&(ppp_ptr -> nx_ppp_thread));
9331 
9332     /* Deactivate the PPP timer.  */
9333     tx_timer_deactivate(&(ppp_ptr -> nx_ppp_timer));
9334 
9335     /* Delete the PPP timer.  */
9336     tx_timer_delete(&(ppp_ptr -> nx_ppp_timer));
9337 
9338     /* Delete the event flag group.  */
9339     tx_event_flags_delete(&(ppp_ptr -> nx_ppp_event));
9340 
9341     /* Return success.  */
9342     return(NX_SUCCESS);
9343 }
9344 
9345 
9346 /**************************************************************************/
9347 /*                                                                        */
9348 /*  FUNCTION                                               RELEASE        */
9349 /*                                                                        */
9350 /*    _nxe_ppp_link_up_notify                             PORTABLE C      */
9351 /*                                                           6.1          */
9352 /*  AUTHOR                                                                */
9353 /*                                                                        */
9354 /*    Yuxin Zhou, Microsoft Corporation                                   */
9355 /*                                                                        */
9356 /*  DESCRIPTION                                                           */
9357 /*                                                                        */
9358 /*    This function checks for errors in the PPP link up notify callback  */
9359 /*    notify set function call.                                           */
9360 /*                                                                        */
9361 /*  INPUT                                                                 */
9362 /*                                                                        */
9363 /*    ppp_ptr                               Pointer to instance           */
9364 /*    ppp_link_up_callback                  Pointer to application        */
9365 /*                                            callback function           */
9366 /*                                                                        */
9367 /*  OUTPUT                                                                */
9368 /*                                                                        */
9369 /*    status                                Completion status             */
9370 /*                                                                        */
9371 /*  CALLS                                                                 */
9372 /*                                                                        */
9373 /*    _nx_ppp_link_up_notify                Actual PPP link up notify set */
9374 /*                                            function                    */
9375 /*                                                                        */
9376 /*  CALLED BY                                                             */
9377 /*                                                                        */
9378 /*    Application Code                                                    */
9379 /*                                                                        */
9380 /*  RELEASE HISTORY                                                       */
9381 /*                                                                        */
9382 /*    DATE              NAME                      DESCRIPTION             */
9383 /*                                                                        */
9384 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9385 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9386 /*                                            resulting in version 6.1    */
9387 /*                                                                        */
9388 /**************************************************************************/
_nxe_ppp_link_up_notify(NX_PPP * ppp_ptr,VOID (* ppp_link_up_callback)(NX_PPP * ppp_ptr))9389 UINT  _nxe_ppp_link_up_notify(NX_PPP *ppp_ptr, VOID (*ppp_link_up_callback)(NX_PPP *ppp_ptr))
9390 {
9391 
9392 UINT    status;
9393 
9394     /* Check for an invalid input pointer.  */
9395     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
9396         return(NX_PTR_ERROR);
9397 
9398     /* Check for valid caller.  */
9399     NX_INIT_AND_THREADS_CALLER_CHECKING
9400 
9401     /* Call actual PPP link up notify set function.  */
9402     status =  _nx_ppp_link_up_notify(ppp_ptr, ppp_link_up_callback);
9403 
9404     /* Return completion status.  */
9405     return(status);
9406 }
9407 
9408 
9409 /**************************************************************************/
9410 /*                                                                        */
9411 /*  FUNCTION                                               RELEASE        */
9412 /*                                                                        */
9413 /*    _nx_ppp_link_up_notify                              PORTABLE C      */
9414 /*                                                           6.1          */
9415 /*  AUTHOR                                                                */
9416 /*                                                                        */
9417 /*    Yuxin Zhou, Microsoft Corporation                                   */
9418 /*                                                                        */
9419 /*  DESCRIPTION                                                           */
9420 /*                                                                        */
9421 /*    This function registers an application callback for the link up     */
9422 /*    event.                                                              */
9423 /*                                                                        */
9424 /*  INPUT                                                                 */
9425 /*                                                                        */
9426 /*    ppp_ptr                               Pointer to instance           */
9427 /*    ppp_link_up_callback                  Pointer to application        */
9428 /*                                            callback function           */
9429 /*                                                                        */
9430 /*  OUTPUT                                                                */
9431 /*                                                                        */
9432 /*    status                                Completion status             */
9433 /*                                                                        */
9434 /*  CALLS                                                                 */
9435 /*                                                                        */
9436 /*    None                                                                */
9437 /*                                                                        */
9438 /*  CALLED BY                                                             */
9439 /*                                                                        */
9440 /*    Application Code                                                    */
9441 /*                                                                        */
9442 /*  RELEASE HISTORY                                                       */
9443 /*                                                                        */
9444 /*    DATE              NAME                      DESCRIPTION             */
9445 /*                                                                        */
9446 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9447 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9448 /*                                            resulting in version 6.1    */
9449 /*                                                                        */
9450 /**************************************************************************/
_nx_ppp_link_up_notify(NX_PPP * ppp_ptr,VOID (* ppp_link_up_callback)(NX_PPP * ppp_ptr))9451 UINT  _nx_ppp_link_up_notify(NX_PPP *ppp_ptr, VOID (*ppp_link_up_callback)(NX_PPP *ppp_ptr))
9452 {
9453 
9454     /* Valid PPP pointer, now setup the notification callback.  Note that supplying
9455        a NULL for the callback will disable notification.  */
9456     ppp_ptr -> nx_ppp_link_up_callback =  ppp_link_up_callback;
9457 
9458     /* Return success.  */
9459     return(NX_SUCCESS);
9460 }
9461 
9462 
9463 /**************************************************************************/
9464 /*                                                                        */
9465 /*  FUNCTION                                               RELEASE        */
9466 /*                                                                        */
9467 /*    _nxe_ppp_link_down_notify                           PORTABLE C      */
9468 /*                                                           6.1          */
9469 /*  AUTHOR                                                                */
9470 /*                                                                        */
9471 /*    Yuxin Zhou, Microsoft Corporation                                   */
9472 /*                                                                        */
9473 /*  DESCRIPTION                                                           */
9474 /*                                                                        */
9475 /*    This function checks for errors in the PPP link down notify callback*/
9476 /*    notify set function call.                                           */
9477 /*                                                                        */
9478 /*  INPUT                                                                 */
9479 /*                                                                        */
9480 /*    ppp_ptr                               Pointer to instance           */
9481 /*    ppp_link_down_callback                Pointer to application        */
9482 /*                                            callback function           */
9483 /*                                                                        */
9484 /*  OUTPUT                                                                */
9485 /*                                                                        */
9486 /*    status                                Completion status             */
9487 /*                                                                        */
9488 /*  CALLS                                                                 */
9489 /*                                                                        */
9490 /*    _nx_ppp_link_down_notify              Actual PPP link down notify   */
9491 /*                                            set function                */
9492 /*                                                                        */
9493 /*  CALLED BY                                                             */
9494 /*                                                                        */
9495 /*    Application Code                                                    */
9496 /*                                                                        */
9497 /*  RELEASE HISTORY                                                       */
9498 /*                                                                        */
9499 /*    DATE              NAME                      DESCRIPTION             */
9500 /*                                                                        */
9501 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9502 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9503 /*                                            resulting in version 6.1    */
9504 /*                                                                        */
9505 /**************************************************************************/
_nxe_ppp_link_down_notify(NX_PPP * ppp_ptr,VOID (* ppp_link_down_callback)(NX_PPP * ppp_ptr))9506 UINT  _nxe_ppp_link_down_notify(NX_PPP *ppp_ptr, VOID (*ppp_link_down_callback)(NX_PPP *ppp_ptr))
9507 {
9508 
9509 UINT    status;
9510 
9511     /* Check for an invalid input pointer.  */
9512     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
9513         return(NX_PTR_ERROR);
9514 
9515     /* Check for valid caller.  */
9516     NX_INIT_AND_THREADS_CALLER_CHECKING
9517 
9518     /* Call actual PPP link down notify set function.  */
9519     status =  _nx_ppp_link_down_notify(ppp_ptr, ppp_link_down_callback);
9520 
9521     /* Return completion status.  */
9522     return(status);
9523 }
9524 
9525 
9526 /**************************************************************************/
9527 /*                                                                        */
9528 /*  FUNCTION                                               RELEASE        */
9529 /*                                                                        */
9530 /*    _nx_ppp_link_down_notify                            PORTABLE C      */
9531 /*                                                           6.1          */
9532 /*  AUTHOR                                                                */
9533 /*                                                                        */
9534 /*    Yuxin Zhou, Microsoft Corporation                                   */
9535 /*                                                                        */
9536 /*  DESCRIPTION                                                           */
9537 /*                                                                        */
9538 /*    This function registers an application callback for the link down   */
9539 /*    event.                                                              */
9540 /*                                                                        */
9541 /*  INPUT                                                                 */
9542 /*                                                                        */
9543 /*    ppp_ptr                               Pointer to instance           */
9544 /*    ppp_link_down_callback                Pointer to application        */
9545 /*                                            callback function           */
9546 /*                                                                        */
9547 /*  OUTPUT                                                                */
9548 /*                                                                        */
9549 /*    status                                Completion status             */
9550 /*                                                                        */
9551 /*  CALLS                                                                 */
9552 /*                                                                        */
9553 /*    None                                                                */
9554 /*                                                                        */
9555 /*  CALLED BY                                                             */
9556 /*                                                                        */
9557 /*    Application Code                                                    */
9558 /*                                                                        */
9559 /*  RELEASE HISTORY                                                       */
9560 /*                                                                        */
9561 /*    DATE              NAME                      DESCRIPTION             */
9562 /*                                                                        */
9563 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9564 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9565 /*                                            resulting in version 6.1    */
9566 /*                                                                        */
9567 /**************************************************************************/
_nx_ppp_link_down_notify(NX_PPP * ppp_ptr,VOID (* ppp_link_down_callback)(NX_PPP * ppp_ptr))9568 UINT  _nx_ppp_link_down_notify(NX_PPP *ppp_ptr, VOID (*ppp_link_down_callback)(NX_PPP *ppp_ptr))
9569 {
9570 
9571     /* Valid PPP pointer, now setup the notification callback.  Note that supplying
9572        a NULL for the callback will disable notification.  */
9573     ppp_ptr -> nx_ppp_link_down_callback =  ppp_link_down_callback;
9574 
9575     /* Return success.  */
9576     return(NX_SUCCESS);
9577 }
9578 
9579 
9580 /**************************************************************************/
9581 /*                                                                        */
9582 /*  FUNCTION                                               RELEASE        */
9583 /*                                                                        */
9584 /*    _nxe_ppp_pap_enable                                 PORTABLE C      */
9585 /*                                                           6.1          */
9586 /*  AUTHOR                                                                */
9587 /*                                                                        */
9588 /*    Yuxin Zhou, Microsoft Corporation                                   */
9589 /*                                                                        */
9590 /*  DESCRIPTION                                                           */
9591 /*                                                                        */
9592 /*    This function checks for errors in the PPP PAP enable               */
9593 /*    function call.                                                      */
9594 /*                                                                        */
9595 /*    Note: The first string lengths of name and password are limited by  */
9596 /*    internal buffer size. The second string of name and password are    */
9597 /*    NULL terminated.                                                    */
9598 /*                                                                        */
9599 /*  INPUT                                                                 */
9600 /*                                                                        */
9601 /*    ppp_ptr                               Pointer to instance           */
9602 /*    generate_login                        Pointer to login function     */
9603 /*    verify_login                          Pointer to verify function    */
9604 /*                                                                        */
9605 /*  OUTPUT                                                                */
9606 /*                                                                        */
9607 /*    status                                Completion status             */
9608 /*                                                                        */
9609 /*  CALLS                                                                 */
9610 /*                                                                        */
9611 /*    _nx_ppp_pap_enable                    Actual PPP PAP enable function*/
9612 /*                                                                        */
9613 /*  CALLED BY                                                             */
9614 /*                                                                        */
9615 /*    Application Code                                                    */
9616 /*                                                                        */
9617 /*  RELEASE HISTORY                                                       */
9618 /*                                                                        */
9619 /*    DATE              NAME                      DESCRIPTION             */
9620 /*                                                                        */
9621 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9622 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9623 /*                                            resulting in version 6.1    */
9624 /*                                                                        */
9625 /**************************************************************************/
_nxe_ppp_pap_enable(NX_PPP * ppp_ptr,UINT (* generate_login)(CHAR * name,CHAR * password),UINT (* verify_login)(CHAR * name,CHAR * password))9626 UINT  _nxe_ppp_pap_enable(NX_PPP *ppp_ptr, UINT (*generate_login)(CHAR *name, CHAR *password),
9627                         UINT (*verify_login)(CHAR *name, CHAR *password))
9628 {
9629 
9630 UINT    status;
9631 
9632 
9633     /* Check for an invalid input pointer... including not being in the closed state for this configuration API.  */
9634     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED) ||
9635         ((generate_login == NX_NULL) && (verify_login == NX_NULL)))
9636         return(NX_PTR_ERROR);
9637 
9638     /* Check for valid caller.  */
9639     NX_INIT_AND_THREADS_CALLER_CHECKING
9640 
9641     /* Call actual PPP PAP enable function.  */
9642     status =  _nx_ppp_pap_enable(ppp_ptr, generate_login, verify_login);
9643 
9644     /* Return completion status.  */
9645     return(status);
9646 }
9647 
9648 
9649 /**************************************************************************/
9650 /*                                                                        */
9651 /*  FUNCTION                                               RELEASE        */
9652 /*                                                                        */
9653 /*    _nx_ppp_pap_enable                                  PORTABLE C      */
9654 /*                                                           6.1          */
9655 /*  AUTHOR                                                                */
9656 /*                                                                        */
9657 /*    Yuxin Zhou, Microsoft Corporation                                   */
9658 /*                                                                        */
9659 /*  DESCRIPTION                                                           */
9660 /*                                                                        */
9661 /*    This function enables PAP for the specified PPP instance.           */
9662 /*                                                                        */
9663 /*    Note: The first string lengths of name and password are limited by  */
9664 /*    internal buffer size. The second string of name and password are    */
9665 /*    NULL terminated.                                                    */
9666 /*                                                                        */
9667 /*  INPUT                                                                 */
9668 /*                                                                        */
9669 /*    ppp_ptr                               Pointer to PPP instance       */
9670 /*    generate_login                        Pointer to application        */
9671 /*                                            function that generates     */
9672 /*                                            name and password for login */
9673 /*    verify_login                          Pointer to application        */
9674 /*                                            function that verifies the  */
9675 /*                                            supplied name and password  */
9676 /*                                            are valid                   */
9677 /*                                                                        */
9678 /*  OUTPUT                                                                */
9679 /*                                                                        */
9680 /*    status                                Completion status             */
9681 /*                                                                        */
9682 /*  CALLS                                                                 */
9683 /*                                                                        */
9684 /*    None                                                                */
9685 /*                                                                        */
9686 /*  CALLED BY                                                             */
9687 /*                                                                        */
9688 /*    Application Code                                                    */
9689 /*                                                                        */
9690 /*  RELEASE HISTORY                                                       */
9691 /*                                                                        */
9692 /*    DATE              NAME                      DESCRIPTION             */
9693 /*                                                                        */
9694 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9695 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9696 /*                                            resulting in version 6.1    */
9697 /*                                                                        */
9698 /**************************************************************************/
_nx_ppp_pap_enable(NX_PPP * ppp_ptr,UINT (* generate_login)(CHAR * name,CHAR * password),UINT (* verify_login)(CHAR * name,CHAR * password))9699 UINT  _nx_ppp_pap_enable(NX_PPP *ppp_ptr, UINT (*generate_login)(CHAR *name, CHAR *password),
9700                          UINT (*verify_login)(CHAR *name, CHAR *password))
9701 {
9702 
9703 #ifdef NX_PPP_DISABLE_PAP
9704 
9705     /* Return the non implemented error.  */
9706     return(NX_NOT_IMPLEMENTED);
9707 
9708 #else
9709 
9710     /* Setup the PAP information.  */
9711     if (generate_login)
9712     {
9713 
9714         /* Setup login generation information.  */
9715         ppp_ptr -> nx_ppp_pap_generate_login =  generate_login;
9716 
9717         /* The authenticated flag is not cleared for the generate login, since the
9718            peer may choose not to require PAP. */
9719     }
9720 
9721     /* Determine if the generate login is provided.  */
9722     if (verify_login)
9723     {
9724         /* Setup login verification information.  */
9725         ppp_ptr -> nx_ppp_pap_verify_login =                  verify_login;
9726         ppp_ptr -> nx_ppp_verify_authentication_protocol =    NX_PPP_PAP_PROTOCOL;
9727 
9728         /* Authentication is needed, clear the flag.  */
9729         ppp_ptr -> nx_ppp_authenticated =  NX_FALSE;
9730     }
9731 
9732     /* Show that the PAP is enabled.  */
9733     ppp_ptr -> nx_ppp_pap_enabled =  NX_TRUE;
9734 
9735     /* Set the initial PAP state.  */
9736     ppp_ptr -> nx_ppp_pap_state =  NX_PPP_PAP_INITIAL_STATE;
9737 
9738     /* Return success.  */
9739     return(NX_SUCCESS);
9740 #endif
9741 }
9742 
9743 
9744 /**************************************************************************/
9745 /*                                                                        */
9746 /*  FUNCTION                                               RELEASE        */
9747 /*                                                                        */
9748 /*    _nxe_ppp_chap_challenge                             PORTABLE C      */
9749 /*                                                           6.1          */
9750 /*  AUTHOR                                                                */
9751 /*                                                                        */
9752 /*    Yuxin Zhou, Microsoft Corporation                                   */
9753 /*                                                                        */
9754 /*  DESCRIPTION                                                           */
9755 /*                                                                        */
9756 /*    This function checks for errors in the PPP CHAP challenge           */
9757 /*    function call.                                                      */
9758 /*                                                                        */
9759 /*  INPUT                                                                 */
9760 /*                                                                        */
9761 /*    ppp_ptr                               Pointer to instance           */
9762 /*                                                                        */
9763 /*  OUTPUT                                                                */
9764 /*                                                                        */
9765 /*    status                                Completion status             */
9766 /*                                                                        */
9767 /*  CALLS                                                                 */
9768 /*                                                                        */
9769 /*    _nx_ppp_chap_challenge                Actual PPP CHAP challenge     */
9770 /*                                            function                    */
9771 /*                                                                        */
9772 /*  CALLED BY                                                             */
9773 /*                                                                        */
9774 /*    Application Code                                                    */
9775 /*                                                                        */
9776 /*  RELEASE HISTORY                                                       */
9777 /*                                                                        */
9778 /*    DATE              NAME                      DESCRIPTION             */
9779 /*                                                                        */
9780 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9781 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9782 /*                                            resulting in version 6.1    */
9783 /*                                                                        */
9784 /**************************************************************************/
_nxe_ppp_chap_challenge(NX_PPP * ppp_ptr)9785 UINT  _nxe_ppp_chap_challenge(NX_PPP *ppp_ptr)
9786 {
9787 
9788 UINT    status;
9789 
9790 
9791     /* Check for an invalid input pointer.  */
9792     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
9793         return(NX_PTR_ERROR);
9794 
9795     /* Check for valid caller.  */
9796     NX_THREADS_ONLY_CALLER_CHECKING
9797 
9798     /* Call actual PPP CHAP challenge function.  */
9799     status =  _nx_ppp_chap_challenge(ppp_ptr);
9800 
9801     /* Return completion status.  */
9802     return(status);
9803 }
9804 
9805 
9806 /**************************************************************************/
9807 /*                                                                        */
9808 /*  FUNCTION                                               RELEASE        */
9809 /*                                                                        */
9810 /*    _nx_ppp_chap_challenge                              PORTABLE C      */
9811 /*                                                           6.1          */
9812 /*  AUTHOR                                                                */
9813 /*                                                                        */
9814 /*    Yuxin Zhou, Microsoft Corporation                                   */
9815 /*                                                                        */
9816 /*  DESCRIPTION                                                           */
9817 /*                                                                        */
9818 /*    This function generates a CHAP challenge for the specified PPP      */
9819 /*    instance.                                                           */
9820 /*                                                                        */
9821 /*  INPUT                                                                 */
9822 /*                                                                        */
9823 /*    ppp_ptr                               Pointer to PPP instance       */
9824 /*                                                                        */
9825 /*  OUTPUT                                                                */
9826 /*                                                                        */
9827 /*    status                                Completion status             */
9828 /*                                                                        */
9829 /*  CALLS                                                                 */
9830 /*                                                                        */
9831 /*    tx_event_flags_set                    Notify PPP receiving thread   */
9832 /*                                                                        */
9833 /*  CALLED BY                                                             */
9834 /*                                                                        */
9835 /*    Application Code                                                    */
9836 /*                                                                        */
9837 /*  RELEASE HISTORY                                                       */
9838 /*                                                                        */
9839 /*    DATE              NAME                      DESCRIPTION             */
9840 /*                                                                        */
9841 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9842 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9843 /*                                            resulting in version 6.1    */
9844 /*                                                                        */
9845 /**************************************************************************/
_nx_ppp_chap_challenge(NX_PPP * ppp_ptr)9846 UINT  _nx_ppp_chap_challenge(NX_PPP *ppp_ptr)
9847 {
9848 
9849 #ifdef NX_PPP_DISABLE_CHAP
9850 
9851     /* Return the non implemented error.  */
9852     return(NX_NOT_IMPLEMENTED);
9853 
9854 #else
9855 
9856     /* Determine if the CHAP of the PPP instance is enabled and able to challenge.  */
9857     if ((ppp_ptr -> nx_ppp_chap_enabled) &&
9858         (ppp_ptr -> nx_ppp_chap_get_challenge_values) &&
9859         (ppp_ptr -> nx_ppp_chap_get_verification_values))
9860     {
9861 
9862         /* Check for the appropriate CHAP state. If the initial CHAP has not yet
9863            completed, simply discard this request.  */
9864         if (ppp_ptr -> nx_ppp_chap_state == NX_PPP_CHAP_COMPLETED_STATE)
9865         {
9866 
9867             /* Yes, the CHAP protocol is in an open state so another challenge is legal.  */
9868 
9869             /* Initiate CHAP challenge by setting the appropriate event flag to wakeup the PPP thread.  */
9870             tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_CHAP_CHALLENGE, TX_OR);
9871         }
9872 
9873         /* Return successful completion.  */
9874         return(NX_SUCCESS);
9875     }
9876     else
9877     {
9878 
9879         /* CHAP is either not enabled or is setup only for CHAP response - not a challenge. Return an error!  */
9880         return(NX_PPP_FAILURE);
9881     }
9882 #endif
9883 }
9884 
9885 
9886 /**************************************************************************/
9887 /*                                                                        */
9888 /*  FUNCTION                                               RELEASE        */
9889 /*                                                                        */
9890 /*    _nxe_ppp_chap_enable                                PORTABLE C      */
9891 /*                                                           6.1          */
9892 /*  AUTHOR                                                                */
9893 /*                                                                        */
9894 /*    Yuxin Zhou, Microsoft Corporation                                   */
9895 /*                                                                        */
9896 /*  DESCRIPTION                                                           */
9897 /*                                                                        */
9898 /*    This function checks for errors in the PPP CHAP enable              */
9899 /*    function call.                                                      */
9900 /*                                                                        */
9901 /*    Note: The string lengths of rand_value, name, system and secret are */
9902 /*    limited by internal buffer size.                                    */
9903 /*                                                                        */
9904 /*  INPUT                                                                 */
9905 /*                                                                        */
9906 /*    ppp_ptr                               Pointer to instance           */
9907 /*    get_challenge_values                  Pointer to application        */
9908 /*                                            function that retrieves     */
9909 /*                                            values required to make     */
9910 /*                                            a challenge                 */
9911 /*    get_responder_values                  Pointer to application        */
9912 /*                                            function that retrieves     */
9913 /*                                            values required to respond  */
9914 /*                                            to a challenge              */
9915 /*    get_verification_values               Pointer to application        */
9916 /*                                            function that retrieves     */
9917 /*                                            values required to verify   */
9918 /*                                            a challenge                 */
9919 /*                                                                        */
9920 /*  OUTPUT                                                                */
9921 /*                                                                        */
9922 /*    status                                Completion status             */
9923 /*                                                                        */
9924 /*  CALLS                                                                 */
9925 /*                                                                        */
9926 /*    _nx_ppp_chap_enable                   Actual PPP CHAP enable        */
9927 /*                                            function                    */
9928 /*                                                                        */
9929 /*  CALLED BY                                                             */
9930 /*                                                                        */
9931 /*    Application Code                                                    */
9932 /*                                                                        */
9933 /*  RELEASE HISTORY                                                       */
9934 /*                                                                        */
9935 /*    DATE              NAME                      DESCRIPTION             */
9936 /*                                                                        */
9937 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
9938 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
9939 /*                                            resulting in version 6.1    */
9940 /*                                                                        */
9941 /**************************************************************************/
_nxe_ppp_chap_enable(NX_PPP * ppp_ptr,UINT (* get_challenge_values)(CHAR * rand_value,CHAR * id,CHAR * name),UINT (* get_responder_values)(CHAR * system,CHAR * name,CHAR * secret),UINT (* get_verification_values)(CHAR * system,CHAR * name,CHAR * secret))9942 UINT  _nxe_ppp_chap_enable(NX_PPP *ppp_ptr,
9943                            UINT (*get_challenge_values)(CHAR *rand_value, CHAR *id, CHAR *name),
9944                            UINT (*get_responder_values)(CHAR *system, CHAR *name, CHAR *secret),
9945                            UINT (*get_verification_values)(CHAR *system, CHAR *name, CHAR *secret))
9946 {
9947 
9948 UINT    status;
9949 
9950 
9951     /* Check for an invalid input pointer... including not being in the closed state for this configuration API.  */
9952     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED) ||
9953         ((get_challenge_values == NX_NULL) && (get_responder_values == NX_NULL) && (get_verification_values == NX_NULL)))
9954         return(NX_PTR_ERROR);
9955 
9956     /* Check for valid caller.  */
9957     NX_INIT_AND_THREADS_CALLER_CHECKING
9958 
9959     /* Call actual PPP CHAP enable function.  */
9960     status =  _nx_ppp_chap_enable(ppp_ptr, get_challenge_values, get_responder_values, get_verification_values);
9961 
9962     /* Return completion status.  */
9963     return(status);
9964 }
9965 
9966 
9967 /**************************************************************************/
9968 /*                                                                        */
9969 /*  FUNCTION                                               RELEASE        */
9970 /*                                                                        */
9971 /*    _nx_ppp_chap_enable                                 PORTABLE C      */
9972 /*                                                           6.1          */
9973 /*  AUTHOR                                                                */
9974 /*                                                                        */
9975 /*    Yuxin Zhou, Microsoft Corporation                                   */
9976 /*                                                                        */
9977 /*  DESCRIPTION                                                           */
9978 /*                                                                        */
9979 /*    This function enables CHAP for the specified PPP instance.          */
9980 /*                                                                        */
9981 /*    Note: The string lengths of rand_value, name, system and secret are */
9982 /*    limited by internal buffer size.                                    */
9983 /*                                                                        */
9984 /*  INPUT                                                                 */
9985 /*                                                                        */
9986 /*    ppp_ptr                               Pointer to PPP instance       */
9987 /*    get_challenge_values                  Pointer to application        */
9988 /*                                            function that retrieves     */
9989 /*                                            values required to make     */
9990 /*                                            a challenge                 */
9991 /*    get_responder_values                  Pointer to application        */
9992 /*                                            function that retrieves     */
9993 /*                                            values required to respond  */
9994 /*                                            to a challenge              */
9995 /*    get_verification_values               Pointer to application        */
9996 /*                                            function that retrieves     */
9997 /*                                            values required to verify   */
9998 /*                                            a challenge response        */
9999 /*                                                                        */
10000 /*  OUTPUT                                                                */
10001 /*                                                                        */
10002 /*    status                                Completion status             */
10003 /*                                                                        */
10004 /*  CALLS                                                                 */
10005 /*                                                                        */
10006 /*    None                                                                */
10007 /*                                                                        */
10008 /*  CALLED BY                                                             */
10009 /*                                                                        */
10010 /*    Application Code                                                    */
10011 /*                                                                        */
10012 /*  RELEASE HISTORY                                                       */
10013 /*                                                                        */
10014 /*    DATE              NAME                      DESCRIPTION             */
10015 /*                                                                        */
10016 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10017 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10018 /*                                            resulting in version 6.1    */
10019 /*                                                                        */
10020 /**************************************************************************/
_nx_ppp_chap_enable(NX_PPP * ppp_ptr,UINT (* get_challenge_values)(CHAR * rand_value,CHAR * id,CHAR * name),UINT (* get_responder_values)(CHAR * system,CHAR * name,CHAR * secret),UINT (* get_verification_values)(CHAR * system,CHAR * name,CHAR * secret))10021 UINT  _nx_ppp_chap_enable(NX_PPP *ppp_ptr,
10022                           UINT (*get_challenge_values)(CHAR *rand_value, CHAR *id, CHAR *name),
10023                           UINT (*get_responder_values)(CHAR *system, CHAR *name, CHAR *secret),
10024                           UINT (*get_verification_values)(CHAR *system, CHAR *name, CHAR *secret))
10025 {
10026 
10027 #ifdef NX_PPP_DISABLE_CHAP
10028 
10029     /* Return the non implemented error.  */
10030     return(NX_NOT_IMPLEMENTED);
10031 
10032 #else
10033 
10034     /* Setup CHAP information.  */
10035     if (get_responder_values)
10036     {
10037 
10038         /* Setup challenge response callback.  */
10039         ppp_ptr -> nx_ppp_chap_get_responder_values =     get_responder_values;
10040 
10041         /* The authenticated flag is not cleared for the generate login, since the
10042            peer may choose not to require CHAP. */
10043     }
10044 
10045     /* Determine if we are going to challenge the peer.  */
10046     if ((get_challenge_values) && (get_verification_values))
10047     {
10048 
10049         /* Setup the CHAP information.  */
10050         ppp_ptr -> nx_ppp_chap_get_challenge_values =     get_challenge_values;
10051         ppp_ptr -> nx_ppp_chap_get_verification_values =  get_verification_values;
10052 
10053         /* Yes, we must generate a challenge.   */
10054         ppp_ptr -> nx_ppp_verify_authentication_protocol =  NX_PPP_CHAP_PROTOCOL;
10055         ppp_ptr -> nx_ppp_authenticated =                   NX_FALSE;
10056     }
10057 
10058     /* Show that the CHAP is enabled.  */
10059     ppp_ptr -> nx_ppp_chap_enabled =  NX_TRUE;
10060 
10061     /* Set the initial CHAP state.  */
10062     ppp_ptr -> nx_ppp_chap_state =  NX_PPP_CHAP_INITIAL_STATE;
10063 
10064     /* Return success.  */
10065     return(NX_SUCCESS);
10066 #endif
10067 }
10068 
10069 
10070 /**************************************************************************/
10071 /*                                                                        */
10072 /*  FUNCTION                                               RELEASE        */
10073 /*                                                                        */
10074 /*    _nxe_ppp_dns_address_get                            PORTABLE C      */
10075 /*                                                           6.1          */
10076 /*  AUTHOR                                                                */
10077 /*                                                                        */
10078 /*    Yuxin Zhou, Microsoft Corporation                                   */
10079 /*                                                                        */
10080 /*  DESCRIPTION                                                           */
10081 /*                                                                        */
10082 /*    This function checks for errors in the DNS address of the PPP       */
10083 /*    instance get function call.                                         */
10084 /*                                                                        */
10085 /*  INPUT                                                                 */
10086 /*                                                                        */
10087 /*    ppp_ptr                               Pointer to PPP instance       */
10088 /*    dns_address_ptr                       Destination for DNS address   */
10089 /*                                                                        */
10090 /*  OUTPUT                                                                */
10091 /*                                                                        */
10092 /*    status                                Completion status             */
10093 /*                                                                        */
10094 /*  CALLS                                                                 */
10095 /*                                                                        */
10096 /*    _nx_ppp_dns_address_get               Actual PPP DNS address get    */
10097 /*                                            function                    */
10098 /*                                                                        */
10099 /*  CALLED BY                                                             */
10100 /*                                                                        */
10101 /*    Application Code                                                    */
10102 /*                                                                        */
10103 /*  RELEASE HISTORY                                                       */
10104 /*                                                                        */
10105 /*    DATE              NAME                      DESCRIPTION             */
10106 /*                                                                        */
10107 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10108 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10109 /*                                            resulting in version 6.1    */
10110 /*                                                                        */
10111 /**************************************************************************/
_nxe_ppp_dns_address_get(NX_PPP * ppp_ptr,ULONG * dns_address_ptr)10112 UINT  _nxe_ppp_dns_address_get(NX_PPP *ppp_ptr, ULONG *dns_address_ptr)
10113 {
10114 
10115 UINT    status;
10116 
10117     /* Check for an invalid input pointer...  */
10118     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) ||
10119         (dns_address_ptr == NX_NULL))
10120         return(NX_PTR_ERROR);
10121 
10122     /* Check for valid caller.  */
10123     NX_THREADS_ONLY_CALLER_CHECKING
10124 
10125     /* Call actual PPP DNS address get function.  */
10126     status =  _nx_ppp_dns_address_get(ppp_ptr, dns_address_ptr);
10127 
10128     /* Return completion status.  */
10129     return(status);
10130 }
10131 
10132 
10133 /**************************************************************************/
10134 /*                                                                        */
10135 /*  FUNCTION                                               RELEASE        */
10136 /*                                                                        */
10137 /*    _nx_ppp_dns_address_get                             PORTABLE C      */
10138 /*                                                           6.1          */
10139 /*  AUTHOR                                                                */
10140 /*                                                                        */
10141 /*    Yuxin Zhou, Microsoft Corporation                                   */
10142 /*                                                                        */
10143 /*  DESCRIPTION                                                           */
10144 /*                                                                        */
10145 /*    This function retrieves the DNS address of the PPP instance.        */
10146 /*                                                                        */
10147 /*  INPUT                                                                 */
10148 /*                                                                        */
10149 /*    ppp_ptr                               Pointer to PPP instance       */
10150 /*    dns_address_ptr                       Destination for DNS address   */
10151 /*                                                                        */
10152 /*  OUTPUT                                                                */
10153 /*                                                                        */
10154 /*    status                                Completion status             */
10155 /*                                                                        */
10156 /*  CALLS                                                                 */
10157 /*                                                                        */
10158 /*    None                                                                */
10159 /*                                                                        */
10160 /*  CALLED BY                                                             */
10161 /*                                                                        */
10162 /*    Application Code                                                    */
10163 /*                                                                        */
10164 /*  RELEASE HISTORY                                                       */
10165 /*                                                                        */
10166 /*    DATE              NAME                      DESCRIPTION             */
10167 /*                                                                        */
10168 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10169 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10170 /*                                            resulting in version 6.1    */
10171 /*                                                                        */
10172 /**************************************************************************/
_nx_ppp_dns_address_get(NX_PPP * ppp_ptr,ULONG * dns_address_ptr)10173 UINT  _nx_ppp_dns_address_get(NX_PPP *ppp_ptr, ULONG *dns_address_ptr)
10174 {
10175 
10176     /* Determine if the PPP instance is in an established state.  */
10177     if (ppp_ptr -> nx_ppp_state == NX_PPP_ESTABLISHED)
10178     {
10179 
10180         if (ppp_ptr -> nx_ppp_primary_dns_address == 0x0)
10181         {
10182             return NX_PPP_ADDRESS_NOT_ESTABLISHED;
10183         }
10184 
10185         /* Return the DNS address ptr.  */
10186         *dns_address_ptr =  ppp_ptr -> nx_ppp_primary_dns_address;
10187 
10188         /* Return success.  */
10189         return(NX_SUCCESS);
10190     }
10191     else
10192     {
10193 
10194         /* Set the DNS address to 0.  */
10195         *dns_address_ptr =  0;
10196 
10197         /* The PPP connection has not yet been established.  */
10198         return(NX_PPP_NOT_ESTABLISHED);
10199     }
10200 }
10201 
10202 
10203 /**************************************************************************/
10204 /*                                                                        */
10205 /*  FUNCTION                                               RELEASE        */
10206 /*                                                                        */
10207 /*    _nxe_ppp_dns_address_set                            PORTABLE C      */
10208 /*                                                           6.1          */
10209 /*  AUTHOR                                                                */
10210 /*                                                                        */
10211 /*    Yuxin Zhou, Microsoft Corporation                                   */
10212 /*                                                                        */
10213 /*  DESCRIPTION                                                           */
10214 /*                                                                        */
10215 /*    This function checks for errors in the DNS address of the PPP       */
10216 /*    instance set function call.                                         */
10217 /*                                                                        */
10218 /*  INPUT                                                                 */
10219 /*                                                                        */
10220 /*    ppp_ptr                               Pointer to PPP instance       */
10221 /*    dns_address                           Primary DNS address           */
10222 /*                                                                        */
10223 /*  OUTPUT                                                                */
10224 /*                                                                        */
10225 /*    status                                Completion status             */
10226 /*                                                                        */
10227 /*  CALLS                                                                 */
10228 /*                                                                        */
10229 /*    _nx_ppp_dns_address_set               Actual PPP DNS address set    */
10230 /*                                            function                    */
10231 /*                                                                        */
10232 /*  CALLED BY                                                             */
10233 /*                                                                        */
10234 /*    Application Code                                                    */
10235 /*                                                                        */
10236 /*  RELEASE HISTORY                                                       */
10237 /*                                                                        */
10238 /*    DATE              NAME                      DESCRIPTION             */
10239 /*                                                                        */
10240 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10241 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10242 /*                                            resulting in version 6.1    */
10243 /*                                                                        */
10244 /**************************************************************************/
_nxe_ppp_dns_address_set(NX_PPP * ppp_ptr,ULONG dns_address)10245 UINT  _nxe_ppp_dns_address_set(NX_PPP *ppp_ptr, ULONG dns_address)
10246 {
10247 
10248 UINT    status;
10249 
10250     /* Check for an invalid input pointer...  */
10251     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
10252         return(NX_PTR_ERROR);
10253 
10254     /* Check for invalid address. */
10255     if (dns_address == 0x0)
10256         return(NX_PPP_INVALID_PARAMETER);
10257 
10258     /* Check for valid caller.  */
10259     NX_INIT_AND_THREADS_CALLER_CHECKING
10260 
10261     /* Call actual PPP DNS address set function.  */
10262     status =  _nx_ppp_dns_address_set(ppp_ptr, dns_address);
10263 
10264     /* Return completion status.  */
10265     return(status);
10266 }
10267 
10268 
10269 /**************************************************************************/
10270 /*                                                                        */
10271 /*  FUNCTION                                               RELEASE        */
10272 /*                                                                        */
10273 /*    _nx_ppp_dns_address_set                             PORTABLE C      */
10274 /*                                                           6.1          */
10275 /*  AUTHOR                                                                */
10276 /*                                                                        */
10277 /*    Yuxin Zhou, Microsoft Corporation                                   */
10278 /*                                                                        */
10279 /*  DESCRIPTION                                                           */
10280 /*                                                                        */
10281 /*    This function sets the primary DNS address for the PPP device to    */
10282 /*   supply if it receives a DNS option request (129) in the configure    */
10283 /*   request NAKed list.                                                  */
10284 /*                                                                        */
10285 /*  INPUT                                                                 */
10286 /*                                                                        */
10287 /*    ppp_ptr                               Pointer to PPP instance       */
10288 /*    dns_address                           Primary DNS address           */
10289 /*                                                                        */
10290 /*  OUTPUT                                                                */
10291 /*                                                                        */
10292 /*    status                                Completion status             */
10293 /*                                                                        */
10294 /*  CALLS                                                                 */
10295 /*                                                                        */
10296 /*    None                                                                */
10297 /*                                                                        */
10298 /*  CALLED BY                                                             */
10299 /*                                                                        */
10300 /*    Application Code                                                    */
10301 /*                                                                        */
10302 /*  RELEASE HISTORY                                                       */
10303 /*                                                                        */
10304 /*    DATE              NAME                      DESCRIPTION             */
10305 /*                                                                        */
10306 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10307 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10308 /*                                            resulting in version 6.1    */
10309 /*                                                                        */
10310 /**************************************************************************/
_nx_ppp_dns_address_set(NX_PPP * ppp_ptr,ULONG dns_address)10311 UINT  _nx_ppp_dns_address_set(NX_PPP *ppp_ptr, ULONG dns_address)
10312 {
10313 
10314     /* Set the primary DNS address.  */
10315     ppp_ptr -> nx_ppp_primary_dns_address = dns_address;
10316 
10317     /* Return success.  */
10318     return NX_SUCCESS;
10319 }
10320 
10321 
10322 /**************************************************************************/
10323 /*                                                                        */
10324 /*  FUNCTION                                               RELEASE        */
10325 /*                                                                        */
10326 /*    _nxe_ppp_secondary_dns_address_get                  PORTABLE C      */
10327 /*                                                           6.1          */
10328 /*  AUTHOR                                                                */
10329 /*                                                                        */
10330 /*    Yuxin Zhou, Microsoft Corporation                                   */
10331 /*                                                                        */
10332 /*  DESCRIPTION                                                           */
10333 /*                                                                        */
10334 /*    This function checks for errors in the secondary DNS address of the */
10335 /*    PPP instance get function call.                                     */
10336 /*                                                                        */
10337 /*  INPUT                                                                 */
10338 /*                                                                        */
10339 /*    ppp_ptr                               Pointer to PPP instance       */
10340 /*    secondary_dns_address_ptr             Secondary DNS address         */
10341 /*                                                                        */
10342 /*  OUTPUT                                                                */
10343 /*                                                                        */
10344 /*    status                                Completion status             */
10345 /*                                                                        */
10346 /*  CALLS                                                                 */
10347 /*                                                                        */
10348 /*    _nx_ppp_secondary_dns_address_get     Actual PPP secondary DNS      */
10349 /*                                            address get function        */
10350 /*                                                                        */
10351 /*  CALLED BY                                                             */
10352 /*                                                                        */
10353 /*    Application Code                                                    */
10354 /*                                                                        */
10355 /*  RELEASE HISTORY                                                       */
10356 /*                                                                        */
10357 /*    DATE              NAME                      DESCRIPTION             */
10358 /*                                                                        */
10359 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10360 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10361 /*                                            resulting in version 6.1    */
10362 /*                                                                        */
10363 /**************************************************************************/
_nxe_ppp_secondary_dns_address_get(NX_PPP * ppp_ptr,ULONG * secondary_dns_address_ptr)10364 UINT  _nxe_ppp_secondary_dns_address_get(NX_PPP *ppp_ptr, ULONG *secondary_dns_address_ptr)
10365 {
10366 
10367 UINT    status;
10368 
10369     /* Check for an invalid input pointer...  */
10370     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) ||
10371         (secondary_dns_address_ptr == NX_NULL))
10372         return(NX_PTR_ERROR);
10373 
10374     /* Check for valid caller.  */
10375     NX_THREADS_ONLY_CALLER_CHECKING
10376 
10377     /* Call actual PPP secondary DNS address get function.  */
10378     status =  _nx_ppp_secondary_dns_address_get(ppp_ptr, secondary_dns_address_ptr);
10379 
10380     /* Return completion status.  */
10381     return(status);
10382 }
10383 
10384 
10385 /**************************************************************************/
10386 /*                                                                        */
10387 /*  FUNCTION                                               RELEASE        */
10388 /*                                                                        */
10389 /*    _nx_ppp_secondary_dns_address_get                   PORTABLE C      */
10390 /*                                                           6.1          */
10391 /*  AUTHOR                                                                */
10392 /*                                                                        */
10393 /*    Yuxin Zhou, Microsoft Corporation                                   */
10394 /*                                                                        */
10395 /*  DESCRIPTION                                                           */
10396 /*                                                                        */
10397 /*    This function retrieves the secondary DNS address of the PPP        */
10398 /*    instance.                                                           */
10399 /*                                                                        */
10400 /*  INPUT                                                                 */
10401 /*                                                                        */
10402 /*    ppp_ptr                               Pointer to PPP instance       */
10403 /*    secondary_dns_address_ptr             Secondary DNS address         */
10404 /*                                                                        */
10405 /*  OUTPUT                                                                */
10406 /*                                                                        */
10407 /*    status                                Completion status             */
10408 /*                                                                        */
10409 /*  CALLS                                                                 */
10410 /*                                                                        */
10411 /*    None                                                                */
10412 /*                                                                        */
10413 /*  CALLED BY                                                             */
10414 /*                                                                        */
10415 /*    Application Code                                                    */
10416 /*                                                                        */
10417 /*  RELEASE HISTORY                                                       */
10418 /*                                                                        */
10419 /*    DATE              NAME                      DESCRIPTION             */
10420 /*                                                                        */
10421 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10422 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10423 /*                                            resulting in version 6.1    */
10424 /*                                                                        */
10425 /**************************************************************************/
_nx_ppp_secondary_dns_address_get(NX_PPP * ppp_ptr,ULONG * secondary_dns_address_ptr)10426 UINT  _nx_ppp_secondary_dns_address_get(NX_PPP *ppp_ptr, ULONG *secondary_dns_address_ptr)
10427 {
10428 
10429     /* Determine if the PPP instance is in an established state.  */
10430     if (ppp_ptr -> nx_ppp_state == NX_PPP_ESTABLISHED)
10431     {
10432 
10433         if (ppp_ptr -> nx_ppp_secondary_dns_address == 0x0)
10434         {
10435             return(NX_PPP_ADDRESS_NOT_ESTABLISHED);
10436         }
10437 
10438         /* Return the DNS address ptr.  */
10439         *secondary_dns_address_ptr =  ppp_ptr -> nx_ppp_secondary_dns_address;
10440 
10441         /* Return success.  */
10442         return(NX_SUCCESS);
10443     }
10444     else
10445     {
10446 
10447         /* Set the DNS address to 0.  */
10448         *secondary_dns_address_ptr =  0;
10449 
10450         /* The PPP connection has not yet been established.  */
10451         return(NX_PPP_NOT_ESTABLISHED);
10452     }
10453 }
10454 
10455 
10456 /**************************************************************************/
10457 /*                                                                        */
10458 /*  FUNCTION                                               RELEASE        */
10459 /*                                                                        */
10460 /*    _nxe_ppp_secondary_dns_address_set                  PORTABLE C      */
10461 /*                                                           6.1          */
10462 /*  AUTHOR                                                                */
10463 /*                                                                        */
10464 /*    Yuxin Zhou, Microsoft Corporation                                   */
10465 /*                                                                        */
10466 /*  DESCRIPTION                                                           */
10467 /*                                                                        */
10468 /*    This function checks for errors in the secondary DNS address of the */
10469 /*    PPP instance set function call.                                     */
10470 /*                                                                        */
10471 /*  INPUT                                                                 */
10472 /*                                                                        */
10473 /*    ppp_ptr                               Pointer to PPP instance       */
10474 /*    secondary_dns_address_ptr             Secondary DNS address         */
10475 /*                                                                        */
10476 /*  OUTPUT                                                                */
10477 /*                                                                        */
10478 /*    status                                Completion status             */
10479 /*                                                                        */
10480 /*  CALLS                                                                 */
10481 /*                                                                        */
10482 /*    _nx_ppp_secondary_dns_address_set     Actual PPP secondary DNS      */
10483 /*                                            address set function        */
10484 /*                                                                        */
10485 /*  CALLED BY                                                             */
10486 /*                                                                        */
10487 /*    Application Code                                                    */
10488 /*                                                                        */
10489 /*  RELEASE HISTORY                                                       */
10490 /*                                                                        */
10491 /*    DATE              NAME                      DESCRIPTION             */
10492 /*                                                                        */
10493 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10494 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10495 /*                                            resulting in version 6.1    */
10496 /*                                                                        */
10497 /**************************************************************************/
_nxe_ppp_secondary_dns_address_set(NX_PPP * ppp_ptr,ULONG secondary_dns_address)10498 UINT  _nxe_ppp_secondary_dns_address_set(NX_PPP *ppp_ptr, ULONG secondary_dns_address)
10499 {
10500 
10501 UINT    status;
10502 
10503     /* Check for an invalid input pointer...  */
10504     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
10505         return(NX_PTR_ERROR);
10506 
10507     /* Check for invalid address. */
10508     if (secondary_dns_address == 0x0)
10509         return(NX_PPP_INVALID_PARAMETER);
10510 
10511     /* Check for valid caller.  */
10512     NX_INIT_AND_THREADS_CALLER_CHECKING
10513 
10514     /* Call actual PPP secondary DNS address set function.  */
10515     status =  _nx_ppp_secondary_dns_address_set(ppp_ptr, secondary_dns_address);
10516 
10517     /* Return completion status.  */
10518     return(status);
10519 }
10520 
10521 
10522 /**************************************************************************/
10523 /*                                                                        */
10524 /*  FUNCTION                                               RELEASE        */
10525 /*                                                                        */
10526 /*    _nx_ppp_secondary_dns_address_set                   PORTABLE C      */
10527 /*                                                           6.1          */
10528 /*  AUTHOR                                                                */
10529 /*                                                                        */
10530 /*    Yuxin Zhou, Microsoft Corporation                                   */
10531 /*                                                                        */
10532 /*  DESCRIPTION                                                           */
10533 /*                                                                        */
10534 /*    This function sets the secondary DNS address for the PPP device to  */
10535 /*   supply if it receives a DNS option request (131) in the configure    */
10536 /*   request NAKed list.                                                  */
10537 /*                                                                        */
10538 /*  INPUT                                                                 */
10539 /*                                                                        */
10540 /*    ppp_ptr                               Pointer to PPP instance       */
10541 /*    secondary_dns_address_ptr             Secondary DNS address         */
10542 /*                                                                        */
10543 /*  OUTPUT                                                                */
10544 /*                                                                        */
10545 /*    status                                Completion status             */
10546 /*                                                                        */
10547 /*  CALLS                                                                 */
10548 /*                                                                        */
10549 /*    None                                                                */
10550 /*                                                                        */
10551 /*  CALLED BY                                                             */
10552 /*                                                                        */
10553 /*    Application Code                                                    */
10554 /*                                                                        */
10555 /*  RELEASE HISTORY                                                       */
10556 /*                                                                        */
10557 /*    DATE              NAME                      DESCRIPTION             */
10558 /*                                                                        */
10559 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10560 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10561 /*                                            resulting in version 6.1    */
10562 /*                                                                        */
10563 /**************************************************************************/
_nx_ppp_secondary_dns_address_set(NX_PPP * ppp_ptr,ULONG secondary_dns_address)10564 UINT  _nx_ppp_secondary_dns_address_set(NX_PPP *ppp_ptr, ULONG secondary_dns_address)
10565 {
10566 
10567     /* Set the secondary DNS address.  */
10568     ppp_ptr -> nx_ppp_secondary_dns_address = secondary_dns_address;
10569 
10570     /* Return success.  */
10571     return(NX_SUCCESS);
10572 }
10573 
10574 
10575 /**************************************************************************/
10576 /*                                                                        */
10577 /*  FUNCTION                                               RELEASE        */
10578 /*                                                                        */
10579 /*    _nxe_ppp_interface_index_get                        PORTABLE C      */
10580 /*                                                           6.1          */
10581 /*  AUTHOR                                                                */
10582 /*                                                                        */
10583 /*    Yuxin Zhou, Microsoft Corporation                                   */
10584 /*                                                                        */
10585 /*  DESCRIPTION                                                           */
10586 /*                                                                        */
10587 /*    This function checks for errors in the PPP interface index get      */
10588 /*    function call.                                                      */
10589 /*                                                                        */
10590 /*  INPUT                                                                 */
10591 /*                                                                        */
10592 /*    ppp_ptr                               Pointer to PPP instance       */
10593 /*    index_ptr                             Index of associated interface */
10594 /*                                                                        */
10595 /*  OUTPUT                                                                */
10596 /*                                                                        */
10597 /*    status                                Completion status             */
10598 /*                                                                        */
10599 /*  CALLS                                                                 */
10600 /*                                                                        */
10601 /*    _nxe_ppp_interface_index_get         Actual PPP interface index get */
10602 /*                                           function                     */
10603 /*                                                                        */
10604 /*  CALLED BY                                                             */
10605 /*                                                                        */
10606 /*    Application Code                                                    */
10607 /*                                                                        */
10608 /*  RELEASE HISTORY                                                       */
10609 /*                                                                        */
10610 /*    DATE              NAME                      DESCRIPTION             */
10611 /*                                                                        */
10612 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10613 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10614 /*                                            resulting in version 6.1    */
10615 /*                                                                        */
10616 /**************************************************************************/
_nxe_ppp_interface_index_get(NX_PPP * ppp_ptr,UINT * index_ptr)10617 UINT  _nxe_ppp_interface_index_get(NX_PPP *ppp_ptr, UINT *index_ptr)
10618 {
10619 
10620 UINT    status;
10621 
10622     /* Check for an invalid input pointer.  */
10623     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
10624         return(NX_PTR_ERROR);
10625 
10626     /* Check for valid caller.  */
10627     NX_THREADS_ONLY_CALLER_CHECKING
10628 
10629     /* Call actual PPP interface idnex get function.  */
10630     status =  _nx_ppp_interface_index_get(ppp_ptr, index_ptr);
10631 
10632     /* Return completion status.  */
10633     return(status);
10634 }
10635 
10636 
10637 /**************************************************************************/
10638 /*                                                                        */
10639 /*  FUNCTION                                               RELEASE        */
10640 /*                                                                        */
10641 /*    _nx_ppp_interface_index_get                         PORTABLE C      */
10642 /*                                                           6.1          */
10643 /*  AUTHOR                                                                */
10644 /*                                                                        */
10645 /*    Yuxin Zhou, Microsoft Corporation                                   */
10646 /*                                                                        */
10647 /*  DESCRIPTION                                                           */
10648 /*                                                                        */
10649 /*    This function retrieves the interface index with a particular PPP   */
10650 /*    instance.                                                           */
10651 /*                                                                        */
10652 /*  INPUT                                                                 */
10653 /*                                                                        */
10654 /*    ppp_ptr                               Pointer to PPP instance       */
10655 /*    index_ptr                             Index of associated interface */
10656 /*                                                                        */
10657 /*  OUTPUT                                                                */
10658 /*                                                                        */
10659 /*    status                                Completion status             */
10660 /*                                                                        */
10661 /*  CALLS                                                                 */
10662 /*                                                                        */
10663 /*    None                                                                */
10664 /*                                                                        */
10665 /*  CALLED BY                                                             */
10666 /*                                                                        */
10667 /*    Application Code                                                    */
10668 /*                                                                        */
10669 /*  RELEASE HISTORY                                                       */
10670 /*                                                                        */
10671 /*    DATE              NAME                      DESCRIPTION             */
10672 /*                                                                        */
10673 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10674 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10675 /*                                            resulting in version 6.1    */
10676 /*                                                                        */
10677 /**************************************************************************/
_nx_ppp_interface_index_get(NX_PPP * ppp_ptr,UINT * index_ptr)10678 UINT  _nx_ppp_interface_index_get(NX_PPP *ppp_ptr, UINT *index_ptr)
10679 {
10680 
10681     /* Return the interface index.  */
10682     *index_ptr =  ppp_ptr -> nx_ppp_interface_index;
10683 
10684     /* Determine if the interface is actually setup.  */
10685     if (ppp_ptr -> nx_ppp_interface_ptr)
10686     {
10687 
10688         /* Return success.  */
10689         return(NX_SUCCESS);
10690     }
10691     else
10692     {
10693         /* Return an error. The IP thread has not executed yet which means the
10694            interface has not be setup.  */
10695         return(NX_IN_PROGRESS);
10696     }
10697 }
10698 
10699 
10700 /**************************************************************************/
10701 /*                                                                        */
10702 /*  FUNCTION                                               RELEASE        */
10703 /*                                                                        */
10704 /*    _nxe_ppp_ip_address_assign                          PORTABLE C      */
10705 /*                                                           6.1          */
10706 /*  AUTHOR                                                                */
10707 /*                                                                        */
10708 /*    Yuxin Zhou, Microsoft Corporation                                   */
10709 /*                                                                        */
10710 /*  DESCRIPTION                                                           */
10711 /*                                                                        */
10712 /*    This function checks for errors in the PPP IP address assign        */
10713 /*    function call.                                                      */
10714 /*                                                                        */
10715 /*  INPUT                                                                 */
10716 /*                                                                        */
10717 /*    ppp_ptr                               Pointer to instance           */
10718 /*    local_ip_address                      Local IP address              */
10719 /*    peer_ip_address                       Peer IP address               */
10720 /*                                                                        */
10721 /*  OUTPUT                                                                */
10722 /*                                                                        */
10723 /*    status                                Completion status             */
10724 /*                                                                        */
10725 /*  CALLS                                                                 */
10726 /*                                                                        */
10727 /*    _nx_ppp_ip_address_assign             Actual PPP IP address assign  */
10728 /*                                            function                    */
10729 /*                                                                        */
10730 /*  CALLED BY                                                             */
10731 /*                                                                        */
10732 /*    Application Code                                                    */
10733 /*                                                                        */
10734 /*  RELEASE HISTORY                                                       */
10735 /*                                                                        */
10736 /*    DATE              NAME                      DESCRIPTION             */
10737 /*                                                                        */
10738 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10739 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10740 /*                                            resulting in version 6.1    */
10741 /*                                                                        */
10742 /**************************************************************************/
_nxe_ppp_ip_address_assign(NX_PPP * ppp_ptr,ULONG local_ip_address,ULONG peer_ip_address)10743 UINT  _nxe_ppp_ip_address_assign(NX_PPP *ppp_ptr, ULONG local_ip_address, ULONG peer_ip_address)
10744 {
10745 
10746 UINT    status;
10747 
10748 
10749     /* Check for an invalid input pointer... including not being in the closed state for this configuration API.  */
10750     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED))
10751         return(NX_PTR_ERROR);
10752 
10753     /* Check for valid caller.  */
10754     NX_INIT_AND_THREADS_CALLER_CHECKING
10755 
10756     /* Call actual PPP IP address assign function.  */
10757     status =  _nx_ppp_ip_address_assign(ppp_ptr, local_ip_address, peer_ip_address);
10758 
10759     /* Return completion status.  */
10760     return(status);
10761 }
10762 
10763 
10764 /**************************************************************************/
10765 /*                                                                        */
10766 /*  FUNCTION                                               RELEASE        */
10767 /*                                                                        */
10768 /*    _nx_ppp_ip_address_assign                           PORTABLE C      */
10769 /*                                                           6.1          */
10770 /*  AUTHOR                                                                */
10771 /*                                                                        */
10772 /*    Yuxin Zhou, Microsoft Corporation                                   */
10773 /*                                                                        */
10774 /*  DESCRIPTION                                                           */
10775 /*                                                                        */
10776 /*    This function assigns a local and peer IP address for the           */
10777 /*    specified PPP instance.                                             */
10778 /*                                                                        */
10779 /*  INPUT                                                                 */
10780 /*                                                                        */
10781 /*    ppp_ptr                               Pointer to PPP instance       */
10782 /*    local_ip_address                      Local IP address              */
10783 /*    peer_ip_address                       Peer IP address               */
10784 /*                                                                        */
10785 /*  OUTPUT                                                                */
10786 /*                                                                        */
10787 /*    status                                Completion status             */
10788 /*                                                                        */
10789 /*  CALLS                                                                 */
10790 /*                                                                        */
10791 /*    None                                                                */
10792 /*                                                                        */
10793 /*  CALLED BY                                                             */
10794 /*                                                                        */
10795 /*    Application Code                                                    */
10796 /*                                                                        */
10797 /*  RELEASE HISTORY                                                       */
10798 /*                                                                        */
10799 /*    DATE              NAME                      DESCRIPTION             */
10800 /*                                                                        */
10801 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10802 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10803 /*                                            resulting in version 6.1    */
10804 /*                                                                        */
10805 /**************************************************************************/
_nx_ppp_ip_address_assign(NX_PPP * ppp_ptr,ULONG local_ip_address,ULONG peer_ip_address)10806 UINT  _nx_ppp_ip_address_assign(NX_PPP *ppp_ptr, ULONG local_ip_address, ULONG peer_ip_address)
10807 {
10808 
10809 UINT    i;
10810 
10811 
10812     /* Check if set the local IP address.  */
10813     if (local_ip_address != 0)
10814     {
10815 
10816         /* If true, this PPP instance is a Server. Update the flag.   */
10817         ppp_ptr -> nx_ppp_server = NX_TRUE;
10818     }
10819 
10820     /* Load the IP addresses into the PPP IPCP arrays.  */
10821     i =  4;
10822     do
10823     {
10824 
10825         /* Load the IP values into the array.  */
10826         ppp_ptr -> nx_ppp_ipcp_local_ip[i-1] =  (UCHAR) (local_ip_address & 0xFF);
10827         ppp_ptr -> nx_ppp_ipcp_peer_ip[i-1] = (UCHAR) (peer_ip_address & 0xFF);
10828 
10829         /* Shift the IP address down.  */
10830         local_ip_address =  local_ip_address >> 8;
10831         peer_ip_address = peer_ip_address >> 8;
10832 
10833         /* Decrement the index.  */
10834         i--;
10835 
10836     } while (i);
10837 
10838     /* Return success.  */
10839     return(NX_SUCCESS);
10840 }
10841 
10842 
10843 /**************************************************************************/
10844 /*                                                                        */
10845 /*  FUNCTION                                               RELEASE        */
10846 /*                                                                        */
10847 /*    _nxe_ppp_nak_authentication_notify                  PORTABLE C      */
10848 /*                                                           6.1          */
10849 /*  AUTHOR                                                                */
10850 /*                                                                        */
10851 /*    Yuxin Zhou, Microsoft Corporation                                   */
10852 /*                                                                        */
10853 /*  DESCRIPTION                                                           */
10854 /*                                                                        */
10855 /*    This function checks for errors in the PP NAK authentication notify */
10856 /*    set function call.                                                  */
10857 /*                                                                        */
10858 /*  INPUT                                                                 */
10859 /*                                                                        */
10860 /*    ppp_ptr                               Pointer to PPP instance       */
10861 /*    nak_authentication_notify             Authentication NAK callback   */
10862 /*                                            function                    */
10863 /*                                                                        */
10864 /*  OUTPUT                                                                */
10865 /*                                                                        */
10866 /*    status                                Completion status             */
10867 /*                                                                        */
10868 /*  CALLS                                                                 */
10869 /*                                                                        */
10870 /*    _nx_ppp_nak_authentication_notify     Actual PPP NAK authentication */
10871 /*                                            notify set function         */
10872 /*                                                                        */
10873 /*  CALLED BY                                                             */
10874 /*                                                                        */
10875 /*    Application Code                                                    */
10876 /*                                                                        */
10877 /*  RELEASE HISTORY                                                       */
10878 /*                                                                        */
10879 /*    DATE              NAME                      DESCRIPTION             */
10880 /*                                                                        */
10881 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10882 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10883 /*                                            resulting in version 6.1    */
10884 /*                                                                        */
10885 /**************************************************************************/
_nxe_ppp_nak_authentication_notify(NX_PPP * ppp_ptr,void (* nak_authentication_notify)(void))10886 UINT  _nxe_ppp_nak_authentication_notify(NX_PPP *ppp_ptr, void (*nak_authentication_notify)(void))
10887 {
10888 
10889 UINT    status;
10890 
10891     /* Check for an invalid input pointer... including not being in the closed state for this configuration API.  */
10892     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED))
10893         return(NX_PTR_ERROR);
10894 
10895     /* Check for valid caller.  */
10896     NX_INIT_AND_THREADS_CALLER_CHECKING
10897 
10898     /* Call actual PPP NAK authentication notify set function.  */
10899     status =  _nx_ppp_nak_authentication_notify(ppp_ptr, nak_authentication_notify);
10900 
10901     /* Return completion status.  */
10902     return(status);
10903 }
10904 
10905 
10906 /**************************************************************************/
10907 /*                                                                        */
10908 /*  FUNCTION                                               RELEASE        */
10909 /*                                                                        */
10910 /*    _nx_ppp_nak_authentication_notify                   PORTABLE C      */
10911 /*                                                           6.1          */
10912 /*  AUTHOR                                                                */
10913 /*                                                                        */
10914 /*    Yuxin Zhou, Microsoft Corporation                                   */
10915 /*                                                                        */
10916 /*  DESCRIPTION                                                           */
10917 /*                                                                        */
10918 /*    This function assigns an application callback function to be        */
10919 /*    called if an authentication NAK is received from the peer.          */
10920 /*                                                                        */
10921 /*  INPUT                                                                 */
10922 /*                                                                        */
10923 /*    ppp_ptr                               Pointer to PPP instance       */
10924 /*    nak_authentication_notify             Authentication NAK callback   */
10925 /*                                            function                    */
10926 /*                                                                        */
10927 /*  OUTPUT                                                                */
10928 /*                                                                        */
10929 /*    status                                Completion status             */
10930 /*                                                                        */
10931 /*  CALLS                                                                 */
10932 /*                                                                        */
10933 /*    None                                                                */
10934 /*                                                                        */
10935 /*  CALLED BY                                                             */
10936 /*                                                                        */
10937 /*    Application Code                                                    */
10938 /*                                                                        */
10939 /*  RELEASE HISTORY                                                       */
10940 /*                                                                        */
10941 /*    DATE              NAME                      DESCRIPTION             */
10942 /*                                                                        */
10943 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
10944 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
10945 /*                                            resulting in version 6.1    */
10946 /*                                                                        */
10947 /**************************************************************************/
_nx_ppp_nak_authentication_notify(NX_PPP * ppp_ptr,void (* nak_authentication_notify)(void))10948 UINT  _nx_ppp_nak_authentication_notify(NX_PPP *ppp_ptr, void (*nak_authentication_notify)(void))
10949 {
10950 
10951     /* Store the callback function pointer in the PPP structure.  */
10952     ppp_ptr -> nx_ppp_nak_authentication_notify =  nak_authentication_notify;
10953 
10954     /* Return success.  */
10955     return(NX_SUCCESS);
10956 }
10957 
10958 
10959 /**************************************************************************/
10960 /*                                                                        */
10961 /*  FUNCTION                                               RELEASE        */
10962 /*                                                                        */
10963 /*    _nxe_ppp_raw_string_send                            PORTABLE C      */
10964 /*                                                           6.1          */
10965 /*  AUTHOR                                                                */
10966 /*                                                                        */
10967 /*    Yuxin Zhou, Microsoft Corporation                                   */
10968 /*                                                                        */
10969 /*  DESCRIPTION                                                           */
10970 /*                                                                        */
10971 /*    This function checks for errors in the PPP raw string send          */
10972 /*    function call.                                                      */
10973 /*                                                                        */
10974 /*    Note: The string length of string_ptr is limited by the packet      */
10975 /*    payload size.                                                       */
10976 /*                                                                        */
10977 /*  INPUT                                                                 */
10978 /*                                                                        */
10979 /*    ppp_ptr                               Pointer to instance           */
10980 /*    string_ptr                            Pointer to ASCII string       */
10981 /*                                                                        */
10982 /*  OUTPUT                                                                */
10983 /*                                                                        */
10984 /*    status                                Completion status             */
10985 /*                                                                        */
10986 /*  CALLS                                                                 */
10987 /*                                                                        */
10988 /*    _nx_ppp_raw_string_send               Actual PPP raw string send    */
10989 /*                                            function                    */
10990 /*                                                                        */
10991 /*  CALLED BY                                                             */
10992 /*                                                                        */
10993 /*    Application Code                                                    */
10994 /*                                                                        */
10995 /*  RELEASE HISTORY                                                       */
10996 /*                                                                        */
10997 /*    DATE              NAME                      DESCRIPTION             */
10998 /*                                                                        */
10999 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11000 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11001 /*                                            resulting in version 6.1    */
11002 /*                                                                        */
11003 /**************************************************************************/
_nxe_ppp_raw_string_send(NX_PPP * ppp_ptr,CHAR * string_ptr)11004 UINT  _nxe_ppp_raw_string_send(NX_PPP *ppp_ptr, CHAR *string_ptr)
11005 {
11006 
11007 UINT    status;
11008 
11009 
11010     /* Check for an invalid input pointer.  */
11011     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (string_ptr == NX_NULL))
11012         return(NX_PTR_ERROR);
11013 
11014     /* Check for valid caller.  */
11015     NX_THREADS_ONLY_CALLER_CHECKING
11016 
11017     /* Call actual PPP raw string send function.  */
11018     status =  _nx_ppp_raw_string_send(ppp_ptr, string_ptr);
11019 
11020     /* Return completion status.  */
11021     return(status);
11022 }
11023 
11024 
11025 /**************************************************************************/
11026 /*                                                                        */
11027 /*  FUNCTION                                               RELEASE        */
11028 /*                                                                        */
11029 /*    _nx_ppp_raw_string_send                             PORTABLE C      */
11030 /*                                                           6.1          */
11031 /*  AUTHOR                                                                */
11032 /*                                                                        */
11033 /*    Yuxin Zhou, Microsoft Corporation                                   */
11034 /*                                                                        */
11035 /*  DESCRIPTION                                                           */
11036 /*                                                                        */
11037 /*    This function sends a raw ASCII string to through PPP without any   */
11038 /*    PPP framing. This is useful to respond to modem commands in some    */
11039 /*    applications.                                                       */
11040 /*                                                                        */
11041 /*    Note: The string length of string_ptr is limited by the packet      */
11042 /*    payload size.                                                       */
11043 /*                                                                        */
11044 /*  INPUT                                                                 */
11045 /*                                                                        */
11046 /*    ppp_ptr                               Pointer to PPP instance       */
11047 /*    string_ptr                            Pointer to ASCII string       */
11048 /*                                                                        */
11049 /*  OUTPUT                                                                */
11050 /*                                                                        */
11051 /*    status                                Completion status             */
11052 /*                                                                        */
11053 /*  CALLS                                                                 */
11054 /*                                                                        */
11055 /*    nx_packet_allocate                    Allocate a packet             */
11056 /*    tx_event_flags_set                    Alert PPP thread to process   */
11057 /*                                            raw packet                  */
11058 /*                                                                        */
11059 /*  CALLED BY                                                             */
11060 /*                                                                        */
11061 /*    Application Code                                                    */
11062 /*                                                                        */
11063 /*  RELEASE HISTORY                                                       */
11064 /*                                                                        */
11065 /*    DATE              NAME                      DESCRIPTION             */
11066 /*                                                                        */
11067 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11068 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11069 /*                                            resulting in version 6.1    */
11070 /*                                                                        */
11071 /**************************************************************************/
_nx_ppp_raw_string_send(NX_PPP * ppp_ptr,CHAR * string_ptr)11072 UINT  _nx_ppp_raw_string_send(NX_PPP *ppp_ptr, CHAR *string_ptr)
11073 {
11074 
11075 TX_INTERRUPT_SAVE_AREA
11076 
11077 UINT        i, j;
11078 UINT        status;
11079 NX_PACKET   *packet_ptr;
11080 
11081 
11082     /* Initialize the string index.  */
11083     i =  0;
11084 
11085     /* Loop to process the raw string send request.  */
11086     while (string_ptr[i])
11087     {
11088 
11089         /* Allocate a packet to defer the raw string send to the PPP thread.  */
11090         status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, NX_PPP_TIMEOUT);
11091 
11092         /* Determine if there was an error allocating a packet.  */
11093         if (status != NX_SUCCESS)
11094         {
11095 
11096 #ifndef NX_PPP_DISABLE_INFO
11097 
11098             /* Increment the number of packet allocation timeouts.  */
11099             ppp_ptr -> nx_ppp_packet_allocate_timeouts++;
11100 #endif
11101 
11102             /* Just return an error.  */
11103             return(NX_NO_PACKET);
11104         }
11105 
11106         /* Initialize the packet index.  */
11107         j =  0;
11108 
11109         /* Loop through the string copying the characters into the packet.  */
11110         do
11111         {
11112 
11113             /* Copy character into the packet.  */
11114             packet_ptr -> nx_packet_prepend_ptr[j++] =  (UCHAR)(string_ptr[i++]);
11115 
11116         } while ((string_ptr[i]) && (&(packet_ptr -> nx_packet_prepend_ptr[j]) < packet_ptr -> nx_packet_data_end));
11117 
11118         /* Update the append pointer.  */
11119         packet_ptr -> nx_packet_append_ptr =  &(packet_ptr -> nx_packet_prepend_ptr[j]);
11120 
11121         /* Setup the packet length.  */
11122         packet_ptr -> nx_packet_length =  j;
11123 
11124         /* Now place the packet on the raw packet queue.  */
11125 
11126         /* Disable interrupts.   */
11127         TX_DISABLE
11128 
11129         /* Determine if the raw transmit queue is empty.  */
11130         if (ppp_ptr -> nx_ppp_raw_packet_queue_count++)
11131         {
11132 
11133             /* Not empty, simply link the new packet to the tail and update the tail.  */
11134             (ppp_ptr -> nx_ppp_raw_packet_queue_tail) -> nx_packet_queue_next =  packet_ptr;
11135             ppp_ptr -> nx_ppp_raw_packet_queue_tail =                            packet_ptr;
11136         }
11137         else
11138         {
11139 
11140             /* List is empty, set the head and tail to this packet.  */
11141             ppp_ptr -> nx_ppp_raw_packet_queue_head =  packet_ptr;
11142             ppp_ptr -> nx_ppp_raw_packet_queue_tail =  packet_ptr;
11143         }
11144 
11145         /* Restore interrupts.  */
11146         TX_RESTORE
11147 
11148         /* Set event flag to wake up PPP thread for processing.  */
11149         tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_RAW_STRING_SEND, TX_OR);
11150     }
11151 
11152     /* Return success.  */
11153     return(NX_SUCCESS);
11154 }
11155 
11156 /**************************************************************************/
11157 /*                                                                        */
11158 /*  FUNCTION                                               RELEASE        */
11159 /*                                                                        */
11160 /*    _nxe_ppp_start                                      PORTABLE C      */
11161 /*                                                           6.1          */
11162 /*  AUTHOR                                                                */
11163 /*                                                                        */
11164 /*    Yuxin Zhou, Microsoft Corporation                                   */
11165 /*                                                                        */
11166 /*  DESCRIPTION                                                           */
11167 /*                                                                        */
11168 /*    This function checks for errors in the PPP start function call.     */
11169 /*                                                                        */
11170 /*  INPUT                                                                 */
11171 /*                                                                        */
11172 /*    ppp_ptr                               Pointer to instance           */
11173 /*                                                                        */
11174 /*  OUTPUT                                                                */
11175 /*                                                                        */
11176 /*    status                                Completion status             */
11177 /*                                                                        */
11178 /*  CALLS                                                                 */
11179 /*                                                                        */
11180 /*    _nx_ppp_start                         Actual PPP start function     */
11181 /*                                                                        */
11182 /*  CALLED BY                                                             */
11183 /*                                                                        */
11184 /*    Application Code                                                    */
11185 /*                                                                        */
11186 /*  RELEASE HISTORY                                                       */
11187 /*                                                                        */
11188 /*    DATE              NAME                      DESCRIPTION             */
11189 /*                                                                        */
11190 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11191 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11192 /*                                            resulting in version 6.1    */
11193 /*                                                                        */
11194 /**************************************************************************/
_nxe_ppp_start(NX_PPP * ppp_ptr)11195 UINT  _nxe_ppp_start(NX_PPP *ppp_ptr)
11196 {
11197 
11198 UINT    status;
11199 
11200     /* Check for an invalid input pointer.  */
11201     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
11202         return(NX_PTR_ERROR);
11203 
11204     /* Check for valid caller.  */
11205     NX_THREADS_ONLY_CALLER_CHECKING
11206 
11207     /* Call actual PPP start function.  */
11208     status =  _nx_ppp_start(ppp_ptr);
11209 
11210     /* Return completion status.  */
11211     return(status);
11212 }
11213 
11214 
11215 /**************************************************************************/
11216 /*                                                                        */
11217 /*  FUNCTION                                               RELEASE        */
11218 /*                                                                        */
11219 /*    _nx_ppp_start                                       PORTABLE C      */
11220 /*                                                           6.1          */
11221 /*  AUTHOR                                                                */
11222 /*                                                                        */
11223 /*    Yuxin Zhou, Microsoft Corporation                                   */
11224 /*                                                                        */
11225 /*  DESCRIPTION                                                           */
11226 /*                                                                        */
11227 /*    This function starts the PPP instance.                              */
11228 /*                                                                        */
11229 /*  INPUT                                                                 */
11230 /*                                                                        */
11231 /*    ppp_ptr                               Pointer to instance           */
11232 /*                                                                        */
11233 /*  OUTPUT                                                                */
11234 /*                                                                        */
11235 /*    status                                Completion status             */
11236 /*                                                                        */
11237 /*  CALLS                                                                 */
11238 /*                                                                        */
11239 /*    tx_event_flags_set                    Set PPP event flag to         */
11240 /*                                            start PPP                   */
11241 /*                                                                        */
11242 /*  CALLED BY                                                             */
11243 /*                                                                        */
11244 /*    Application Code                                                    */
11245 /*                                                                        */
11246 /*  RELEASE HISTORY                                                       */
11247 /*                                                                        */
11248 /*    DATE              NAME                      DESCRIPTION             */
11249 /*                                                                        */
11250 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11251 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11252 /*                                            resulting in version 6.1    */
11253 /*                                                                        */
11254 /**************************************************************************/
_nx_ppp_start(NX_PPP * ppp_ptr)11255 UINT  _nx_ppp_start(NX_PPP *ppp_ptr)
11256 {
11257 
11258     /* Determine the current state.  */
11259     if (ppp_ptr -> nx_ppp_state != NX_PPP_STOPPED)
11260     {
11261 
11262         /* Already started.  */
11263         return(NX_PPP_ALREADY_STARTED);
11264     }
11265     else
11266     {
11267 
11268         /* Now restart the PPP instance.  */
11269         tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_START, TX_OR);
11270     }
11271 
11272     /* Return success.  */
11273     return(NX_SUCCESS);
11274 }
11275 
11276 
11277 /**************************************************************************/
11278 /*                                                                        */
11279 /*  FUNCTION                                               RELEASE        */
11280 /*                                                                        */
11281 /*    _nxe_ppp_stop                                       PORTABLE C      */
11282 /*                                                           6.1          */
11283 /*  AUTHOR                                                                */
11284 /*                                                                        */
11285 /*    Yuxin Zhou, Microsoft Corporation                                   */
11286 /*                                                                        */
11287 /*  DESCRIPTION                                                           */
11288 /*                                                                        */
11289 /*    This function checks for errors in the PPP stop function call.      */
11290 /*                                                                        */
11291 /*  INPUT                                                                 */
11292 /*                                                                        */
11293 /*    ppp_ptr                               Pointer to instance           */
11294 /*                                                                        */
11295 /*  OUTPUT                                                                */
11296 /*                                                                        */
11297 /*    status                                Completion status             */
11298 /*                                                                        */
11299 /*  CALLS                                                                 */
11300 /*                                                                        */
11301 /*    _nx_ppp_stop                          Actual PPP stop function      */
11302 /*                                                                        */
11303 /*  CALLED BY                                                             */
11304 /*                                                                        */
11305 /*    Application Code                                                    */
11306 /*                                                                        */
11307 /*  RELEASE HISTORY                                                       */
11308 /*                                                                        */
11309 /*    DATE              NAME                      DESCRIPTION             */
11310 /*                                                                        */
11311 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11312 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11313 /*                                            resulting in version 6.1    */
11314 /*                                                                        */
11315 /**************************************************************************/
_nxe_ppp_stop(NX_PPP * ppp_ptr)11316 UINT  _nxe_ppp_stop(NX_PPP *ppp_ptr)
11317 {
11318 
11319 UINT    status;
11320 
11321     /* Check for an invalid input pointer.  */
11322     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
11323         return(NX_PTR_ERROR);
11324 
11325     /* Check for valid caller.  */
11326     NX_THREADS_ONLY_CALLER_CHECKING
11327 
11328     /* Call actual PPP stop function.  */
11329     status =  _nx_ppp_stop(ppp_ptr);
11330 
11331     /* Return completion status.  */
11332     return(status);
11333 }
11334 
11335 
11336 /**************************************************************************/
11337 /*                                                                        */
11338 /*  FUNCTION                                               RELEASE        */
11339 /*                                                                        */
11340 /*    _nx_ppp_stop                                        PORTABLE C      */
11341 /*                                                           6.1          */
11342 /*  AUTHOR                                                                */
11343 /*                                                                        */
11344 /*    Yuxin Zhou, Microsoft Corporation                                   */
11345 /*                                                                        */
11346 /*  DESCRIPTION                                                           */
11347 /*                                                                        */
11348 /*    This function stops the PPP instance.                               */
11349 /*                                                                        */
11350 /*  INPUT                                                                 */
11351 /*                                                                        */
11352 /*    ppp_ptr                               Pointer to instance           */
11353 /*                                                                        */
11354 /*  OUTPUT                                                                */
11355 /*                                                                        */
11356 /*    status                                Completion status             */
11357 /*                                                                        */
11358 /*  CALLS                                                                 */
11359 /*                                                                        */
11360 /*    tx_event_flags_set                    Set PPP event flag to stop PPP*/
11361 /*                                                                        */
11362 /*  CALLED BY                                                             */
11363 /*                                                                        */
11364 /*    Application Code                                                    */
11365 /*                                                                        */
11366 /*  RELEASE HISTORY                                                       */
11367 /*                                                                        */
11368 /*    DATE              NAME                      DESCRIPTION             */
11369 /*                                                                        */
11370 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11371 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11372 /*                                            resulting in version 6.1    */
11373 /*                                                                        */
11374 /**************************************************************************/
_nx_ppp_stop(NX_PPP * ppp_ptr)11375 UINT  _nx_ppp_stop(NX_PPP *ppp_ptr)
11376 {
11377 
11378 
11379     /* Determine the current state.  */
11380     if (ppp_ptr -> nx_ppp_state == NX_PPP_STOPPED)
11381     {
11382 
11383         /* Already stopped.  */
11384         return(NX_PPP_ALREADY_STOPPED);
11385     }
11386     else
11387     {
11388 
11389         /* Check if LCP connection is already established or in negotiation.  */
11390         if ((ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_COMPLETED_STATE) ||
11391             (ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_CONFIGURE_REQUEST_SENT_STATE) ||
11392             (ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_CONFIGURE_REQUEST_ACKED_STATE) ||
11393             (ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_PEER_CONFIGURE_REQUEST_ACKED_STATE))
11394         {
11395 
11396             /* Setup the retry counter.  */
11397             ppp_ptr -> nx_ppp_protocol_retry_counter = 0;
11398 
11399             /* Setup the timeout.  */
11400             ppp_ptr -> nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT;
11401 
11402             /* Move into the stopping to wait for terminate ack.  */
11403             ppp_ptr -> nx_ppp_lcp_state =  NX_PPP_LCP_STOPPING_STATE;
11404 
11405             /* Send terminate request.  */
11406             _nx_ppp_lcp_terminate_request_send(ppp_ptr);
11407         }
11408         else
11409         {
11410 
11411             /* Set the event to stop the PPP instance.  */
11412             tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
11413 
11414             /* Determine if the application has registered a link down notification
11415                callback.  */
11416             if (ppp_ptr -> nx_ppp_link_down_callback)
11417             {
11418 
11419                 /* Yes, call the application's callback function.  */
11420                 (ppp_ptr -> nx_ppp_link_down_callback)(ppp_ptr);
11421             }
11422         }
11423     }
11424 
11425     /* Return success.  */
11426     return(NX_SUCCESS);
11427 }
11428 
11429 
11430 /**************************************************************************/
11431 /*                                                                        */
11432 /*  FUNCTION                                               RELEASE        */
11433 /*                                                                        */
11434 /*    _nxe_ppp_restart                                    PORTABLE C      */
11435 /*                                                           6.1          */
11436 /*  AUTHOR                                                                */
11437 /*                                                                        */
11438 /*    Yuxin Zhou, Microsoft Corporation                                   */
11439 /*                                                                        */
11440 /*  DESCRIPTION                                                           */
11441 /*                                                                        */
11442 /*    This function checks for errors in the PPP restart function call.   */
11443 /*                                                                        */
11444 /*  INPUT                                                                 */
11445 /*                                                                        */
11446 /*    ppp_ptr                               Pointer to instance           */
11447 /*                                                                        */
11448 /*  OUTPUT                                                                */
11449 /*                                                                        */
11450 /*    status                                Completion status             */
11451 /*                                                                        */
11452 /*  CALLS                                                                 */
11453 /*                                                                        */
11454 /*    _nx_ppp_restart                       Actual PPP restart function   */
11455 /*                                                                        */
11456 /*  CALLED BY                                                             */
11457 /*                                                                        */
11458 /*    Application Code                                                    */
11459 /*                                                                        */
11460 /*  RELEASE HISTORY                                                       */
11461 /*                                                                        */
11462 /*    DATE              NAME                      DESCRIPTION             */
11463 /*                                                                        */
11464 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11465 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11466 /*                                            resulting in version 6.1    */
11467 /*                                                                        */
11468 /**************************************************************************/
_nxe_ppp_restart(NX_PPP * ppp_ptr)11469 UINT  _nxe_ppp_restart(NX_PPP *ppp_ptr)
11470 {
11471 
11472 UINT    status;
11473 
11474     /* Check for an invalid input pointer.  */
11475     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
11476         return(NX_PTR_ERROR);
11477 
11478     /* Check for valid caller.  */
11479     NX_THREADS_ONLY_CALLER_CHECKING
11480 
11481     /* Call actual PPP restart function.  */
11482     status =  _nx_ppp_restart(ppp_ptr);
11483 
11484     /* Return completion status.  */
11485     return(status);
11486 }
11487 
11488 
11489 /**************************************************************************/
11490 /*                                                                        */
11491 /*  FUNCTION                                               RELEASE        */
11492 /*                                                                        */
11493 /*    _nx_ppp_restart                                     PORTABLE C      */
11494 /*                                                           6.1          */
11495 /*  AUTHOR                                                                */
11496 /*                                                                        */
11497 /*    Yuxin Zhou, Microsoft Corporation                                   */
11498 /*                                                                        */
11499 /*  DESCRIPTION                                                           */
11500 /*                                                                        */
11501 /*    This function restarts the PPP instance. This is typically done     */
11502 /*    after a link down situation.                                        */
11503 /*                                                                        */
11504 /*  INPUT                                                                 */
11505 /*                                                                        */
11506 /*    ppp_ptr                               Pointer to instance           */
11507 /*                                                                        */
11508 /*  OUTPUT                                                                */
11509 /*                                                                        */
11510 /*    status                                Completion status             */
11511 /*                                                                        */
11512 /*  CALLS                                                                 */
11513 /*                                                                        */
11514 /*    tx_event_flags_set                    Set PPP event flag to stop PPP*/
11515 /*    tx_thread_sleep                       Sleep for a small time        */
11516 /*                                                                        */
11517 /*  CALLED BY                                                             */
11518 /*                                                                        */
11519 /*    Application Code                                                    */
11520 /*                                                                        */
11521 /*  RELEASE HISTORY                                                       */
11522 /*                                                                        */
11523 /*    DATE              NAME                      DESCRIPTION             */
11524 /*                                                                        */
11525 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11526 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11527 /*                                            resulting in version 6.1    */
11528 /*                                                                        */
11529 /**************************************************************************/
_nx_ppp_restart(NX_PPP * ppp_ptr)11530 UINT  _nx_ppp_restart(NX_PPP *ppp_ptr)
11531 {
11532 
11533     /* Set the event to stop the PPP instance.  */
11534     tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_STOP, TX_OR);
11535 
11536     /* Now restart the PPP instance.  */
11537     tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_START, TX_OR);
11538 
11539     /* Return success.  */
11540     return(NX_SUCCESS);
11541 }
11542 
11543 
11544 /**************************************************************************/
11545 /*                                                                        */
11546 /*  FUNCTION                                               RELEASE        */
11547 /*                                                                        */
11548 /*    _nxe_ppp_status_get                                 PORTABLE C      */
11549 /*                                                           6.1          */
11550 /*  AUTHOR                                                                */
11551 /*                                                                        */
11552 /*    Yuxin Zhou, Microsoft Corporation                                   */
11553 /*                                                                        */
11554 /*  DESCRIPTION                                                           */
11555 /*                                                                        */
11556 /*    This function checks for errors in the PPP status get function call.*/
11557 /*                                                                        */
11558 /*  INPUT                                                                 */
11559 /*                                                                        */
11560 /*    ppp_ptr                               Pointer to PPP instance       */
11561 /*    status_ptr                            Pointer to destination for    */
11562 /*                                            PPP status                  */
11563 /*                                                                        */
11564 /*  OUTPUT                                                                */
11565 /*                                                                        */
11566 /*    status                                Completion status             */
11567 /*                                                                        */
11568 /*  CALLS                                                                 */
11569 /*                                                                        */
11570 /*    _nx_ppp_status_get                    Actual PPP status get function*/
11571 /*                                                                        */
11572 /*  CALLED BY                                                             */
11573 /*                                                                        */
11574 /*    Application Code                                                    */
11575 /*                                                                        */
11576 /*  RELEASE HISTORY                                                       */
11577 /*                                                                        */
11578 /*    DATE              NAME                      DESCRIPTION             */
11579 /*                                                                        */
11580 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11581 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11582 /*                                            resulting in version 6.1    */
11583 /*                                                                        */
11584 /**************************************************************************/
_nxe_ppp_status_get(NX_PPP * ppp_ptr,UINT * status_ptr)11585 UINT  _nxe_ppp_status_get(NX_PPP *ppp_ptr, UINT *status_ptr)
11586 {
11587 
11588 UINT    status;
11589 
11590     /* Check for an invalid input pointer.  */
11591     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID) || (status_ptr == NX_NULL))
11592         return(NX_PTR_ERROR);
11593 
11594     /* Check for valid caller.  */
11595     NX_THREADS_ONLY_CALLER_CHECKING
11596 
11597     /* Call actual PPP status get function.  */
11598     status =  _nx_ppp_status_get(ppp_ptr, status_ptr);
11599 
11600     /* Return completion status.  */
11601     return(status);
11602 }
11603 
11604 
11605 /**************************************************************************/
11606 /*                                                                        */
11607 /*  FUNCTION                                               RELEASE        */
11608 /*                                                                        */
11609 /*    _nx_ppp_status_get                                  PORTABLE C      */
11610 /*                                                           6.1          */
11611 /*  AUTHOR                                                                */
11612 /*                                                                        */
11613 /*    Yuxin Zhou, Microsoft Corporation                                   */
11614 /*                                                                        */
11615 /*  DESCRIPTION                                                           */
11616 /*                                                                        */
11617 /*    This function retrieves the current status of the PPP instance.     */
11618 /*                                                                        */
11619 /*  INPUT                                                                 */
11620 /*                                                                        */
11621 /*    ppp_ptr                               Pointer to PPP instance       */
11622 /*    status_ptr                            Pointer to destination for    */
11623 /*                                            PPP status                  */
11624 /*                                                                        */
11625 /*  OUTPUT                                                                */
11626 /*                                                                        */
11627 /*    status                                Completion status             */
11628 /*                                                                        */
11629 /*  CALLS                                                                 */
11630 /*                                                                        */
11631 /*    None                                                                */
11632 /*                                                                        */
11633 /*  CALLED BY                                                             */
11634 /*                                                                        */
11635 /*    Application Code                                                    */
11636 /*                                                                        */
11637 /*  RELEASE HISTORY                                                       */
11638 /*                                                                        */
11639 /*    DATE              NAME                      DESCRIPTION             */
11640 /*                                                                        */
11641 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11642 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11643 /*                                            resulting in version 6.1    */
11644 /*                                                                        */
11645 /**************************************************************************/
_nx_ppp_status_get(NX_PPP * ppp_ptr,UINT * status_ptr)11646 UINT  _nx_ppp_status_get(NX_PPP *ppp_ptr, UINT *status_ptr)
11647 {
11648 
11649     /* Now determine the current state.  */
11650     if (ppp_ptr -> nx_ppp_state == NX_PPP_ESTABLISHED)
11651     {
11652 
11653         /* PPP is up, return established state.  */
11654         *status_ptr =  NX_PPP_STATUS_ESTABLISHED;
11655 
11656         /* Return success!  */
11657         return(NX_SUCCESS);
11658     }
11659     else if ((ppp_ptr -> nx_ppp_lcp_state > NX_PPP_LCP_INITIAL_STATE) && (ppp_ptr -> nx_ppp_lcp_state < NX_PPP_LCP_COMPLETED_STATE))
11660     {
11661 
11662         /* Is LCP in a failed state?  */
11663         if (ppp_ptr -> nx_ppp_lcp_state == NX_PPP_LCP_FAILED_STATE)
11664         {
11665 
11666             /* Return LCP failed state.  */
11667             *status_ptr =  NX_PPP_STATUS_LCP_FAILED;
11668 
11669             /* Return success.  */
11670             return(NX_SUCCESS);
11671         }
11672         else
11673         {
11674 
11675             /* Return LCP in-progress state.  */
11676             *status_ptr =  NX_PPP_STATUS_LCP_IN_PROGRESS;
11677 
11678             /* Return success.  */
11679             return(NX_SUCCESS);
11680         }
11681     }
11682     else if ((ppp_ptr -> nx_ppp_pap_state > NX_PPP_PAP_INITIAL_STATE) && (ppp_ptr -> nx_ppp_pap_state < NX_PPP_PAP_COMPLETED_STATE))
11683     {
11684 
11685         /* Is PAP in a failed state?  */
11686         if (ppp_ptr -> nx_ppp_pap_state == NX_PPP_PAP_FAILED_STATE)
11687         {
11688 
11689             /* Return PAP failed state.  */
11690             *status_ptr =  NX_PPP_STATUS_PAP_FAILED;
11691 
11692             /* Return success.  */
11693             return(NX_SUCCESS);
11694         }
11695         else
11696         {
11697 
11698             /* Return PAP in-progress state.  */
11699             *status_ptr =  NX_PPP_STATUS_PAP_IN_PROGRESS;
11700 
11701             /* Return success.  */
11702             return(NX_SUCCESS);
11703         }
11704     }
11705     else if ((ppp_ptr -> nx_ppp_chap_state > NX_PPP_CHAP_INITIAL_STATE) && (ppp_ptr -> nx_ppp_chap_state < NX_PPP_CHAP_COMPLETED_STATE))
11706     {
11707 
11708         /* Is CHAP in a failed state?  */
11709         if (ppp_ptr -> nx_ppp_chap_state == NX_PPP_CHAP_CHALLENGE_FAILED_STATE)
11710         {
11711 
11712             /* Return CHAP failed state.  */
11713             *status_ptr =  NX_PPP_STATUS_CHAP_FAILED;
11714 
11715             /* Return success.  */
11716             return(NX_SUCCESS);
11717         }
11718         else
11719         {
11720 
11721             /* Return CHAP in-progress state.  */
11722             *status_ptr =  NX_PPP_STATUS_CHAP_IN_PROGRESS;
11723 
11724             /* Return success.  */
11725             return(NX_SUCCESS);
11726         }
11727     }
11728     else
11729     {
11730 
11731         /* Is IPCP in a failed state?  */
11732         if (ppp_ptr -> nx_ppp_ipcp_state == NX_PPP_IPCP_FAILED_STATE)
11733         {
11734 
11735             /* Return IPCP failed state.  */
11736             *status_ptr =  NX_PPP_STATUS_IPCP_FAILED;
11737 
11738             /* Return success.  */
11739             return(NX_SUCCESS);
11740         }
11741         else
11742         {
11743 
11744             /* Return IPCP in-progress state.  */
11745             *status_ptr =  NX_PPP_STATUS_IPCP_IN_PROGRESS;
11746 
11747             /* Return success.  */
11748             return(NX_SUCCESS);
11749         }
11750     }
11751 }
11752 
11753 
11754 /**************************************************************************/
11755 /*                                                                        */
11756 /*  FUNCTION                                               RELEASE        */
11757 /*                                                                        */
11758 /*    _nx_ppp_lcp_ping_reply                              PORTABLE C      */
11759 /*                                                           6.1          */
11760 /*  AUTHOR                                                                */
11761 /*                                                                        */
11762 /*    Yuxin Zhou, Microsoft Corporation                                   */
11763 /*                                                                        */
11764 /*  DESCRIPTION                                                           */
11765 /*                                                                        */
11766 /* This function is called when the PPP instance detects an LCP echo      */
11767 /* request is received, and retransmits a response.                       */
11768 /*                                                                        */
11769 /*  INPUT                                                                 */
11770 /*                                                                        */
11771 /*    ppp_ptr                               Pointer to PPP instance       */
11772 /*    packet_ptr                            Pointer to echo request packet*/
11773 /*                                             received                   */
11774 /*                                                                        */
11775 /*  OUTPUT                                                                */
11776 /*                                                                        */
11777 /*    None                                  Completion status             */
11778 /*                                                                        */
11779 /*  CALLS                                                                 */
11780 /*                                                                        */
11781 /*    _nx_ppp_packet_transmit               Transmit the PPP data         */
11782 /*                                                                        */
11783 /*  CALLED BY                                                             */
11784 /*                                                                        */
11785 /*    _nx_ppp_lcp_state_machine_update      Processes events and updates  */
11786 /*                                            the PPP in the LCP state    */
11787 /*                                                                        */
11788 /*  RELEASE HISTORY                                                       */
11789 /*                                                                        */
11790 /*    DATE              NAME                      DESCRIPTION             */
11791 /*                                                                        */
11792 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11793 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11794 /*                                            resulting in version 6.1    */
11795 /*                                                                        */
11796 /**************************************************************************/
_nx_ppp_lcp_ping_reply(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)11797 void  _nx_ppp_lcp_ping_reply(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
11798 {
11799 
11800 
11801     /* Change the coding to indicate an Echo reply. */
11802     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_LCP_ECHO_REPLY;
11803 
11804     /* Set the Magic number as zero.  */
11805     packet_ptr -> nx_packet_prepend_ptr[6] = 0;
11806     packet_ptr -> nx_packet_prepend_ptr[7] = 0;
11807     packet_ptr -> nx_packet_prepend_ptr[8] = 0;
11808     packet_ptr -> nx_packet_prepend_ptr[9] = 0;
11809 
11810 #ifndef NX_PPP_DISABLE_INFO
11811 
11812     ppp_ptr -> nx_ppp_lcp_echo_replies_sent++;
11813 
11814 
11815     /* Increment the number of LCP frames sent.  */
11816     ppp_ptr -> nx_ppp_lcp_frames_sent++;
11817 #endif
11818 
11819     /* Send the reply out.  */
11820     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
11821 }
11822 
11823 
11824 /**************************************************************************/
11825 /*                                                                        */
11826 /*  FUNCTION                                               RELEASE        */
11827 /*                                                                        */
11828 /*    _nx_ppp_lcp_ping_process_echo_reply                 PORTABLE C      */
11829 /*                                                           6.1          */
11830 /*  AUTHOR                                                                */
11831 /*                                                                        */
11832 /*    Yuxin Zhou, Microsoft Corporation                                   */
11833 /*                                                                        */
11834 /*  DESCRIPTION                                                           */
11835 /*                                                                        */
11836 /*  This function is called when the PPP instance detects an LCP echo     */
11837 /*  reply is received.  It checks if the reply has a matching ID with the */
11838 /*  previous echo request sent out and if so clears the                   */
11839 /*  nx_ppp_lcp_echo_reply_id to indicate the device received a valid      */
11840 /*  reply.                                                                */
11841 /*                                                                        */
11842 /*  INPUT                                                                 */
11843 /*                                                                        */
11844 /*    ppp_ptr                               Pointer to PPP instance       */
11845 /*    packet_ptr                            Pointer to echo request packet*/
11846 /*                                             received                   */
11847 /*                                                                        */
11848 /*  OUTPUT                                                                */
11849 /*                                                                        */
11850 /*    None                                  Completion status             */
11851 /*                                                                        */
11852 /*  CALLS                                                                 */
11853 /*                                                                        */
11854 /*    None                                                                */
11855 /*                                                                        */
11856 /*  CALLED BY                                                             */
11857 /*                                                                        */
11858 /*    _nx_ppp_lcp_state_machine_update      Processes events and updates  */
11859 /*                                            the PPP in the LCP state    */
11860 /*  RELEASE HISTORY                                                       */
11861 /*                                                                        */
11862 /*    DATE              NAME                      DESCRIPTION             */
11863 /*                                                                        */
11864 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11865 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11866 /*                                            resulting in version 6.1    */
11867 /*                                                                        */
11868 /**************************************************************************/
_nx_ppp_lcp_ping_process_echo_reply(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)11869 void   _nx_ppp_lcp_ping_process_echo_reply(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
11870 {
11871 
11872     /* Verify the PPP ID matches. */
11873     if (packet_ptr -> nx_packet_prepend_ptr[3] == ppp_ptr -> nx_ppp_lcp_echo_reply_id)
11874     {
11875 
11876         /* Successful ping received. */
11877 #ifndef NX_PPP_DISABLE_INFO
11878         /* Increment the number of LCP echo replies received.  */
11879         ppp_ptr -> nx_ppp_lcp_echo_replies_received++;
11880 #endif
11881 
11882         /* Clear the echo ID to indicate we received an LCP echo reply
11883            matching the one we just sent out. */
11884         ppp_ptr -> nx_ppp_lcp_echo_reply_id = 0;
11885     }
11886 }
11887 
11888 
11889 /**************************************************************************/
11890 /*                                                                        */
11891 /*  FUNCTION                                               RELEASE        */
11892 /*                                                                        */
11893 /*    _nxe_ppp_ping_request                               PORTABLE C      */
11894 /*                                                           6.1          */
11895 /*  AUTHOR                                                                */
11896 /*                                                                        */
11897 /*    Yuxin Zhou, Microsoft Corporation                                   */
11898 /*                                                                        */
11899 /*  DESCRIPTION                                                           */
11900 /*                                                                        */
11901 /*    This function performs error checking for the nx_ppp_ping_request   */
11902 /*    service.                                                            */
11903 /*                                                                        */
11904 /*  INPUT                                                                 */
11905 /*                                                                        */
11906 /*    ppp_ptr                               PPP instance pointer          */
11907 /*    data_ptr                              Pointer to data in LCP echo   */
11908 /*    data_size                             Size of data in LCP echo      */
11909 /*    wait_option                           Wait option to transmit echo  */
11910 /*                                                                        */
11911 /*  OUTPUT                                                                */
11912 /*                                                                        */
11913 /*    NX_PTR_ERROR                          Invalid pointer input         */
11914 /*    NX_PPP_INVALID_PARAMETER              Invalid non pointer input     */
11915 /*    NX_SUCCESS                            Successful echo request sent  */
11916 /*    status                                Actual completion status      */
11917 /*                                                                        */
11918 /*  CALLS                                                                 */
11919 /*                                                                        */
11920 /*    _nx_ppp_ping_request                  Actual LCP echo service       */
11921 /*                                                                        */
11922 /*  CALLED BY                                                             */
11923 /*                                                                        */
11924 /*    Application code                                                    */
11925 /*                                                                        */
11926 /*  RELEASE HISTORY                                                       */
11927 /*                                                                        */
11928 /*    DATE              NAME                      DESCRIPTION             */
11929 /*                                                                        */
11930 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11931 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
11932 /*                                            resulting in version 6.1    */
11933 /*                                                                        */
11934 /**************************************************************************/
_nxe_ppp_ping_request(NX_PPP * ppp_ptr,CHAR * data_ptr,ULONG data_size,ULONG wait_option)11935 UINT  _nxe_ppp_ping_request(NX_PPP *ppp_ptr, CHAR *data_ptr, ULONG data_size, ULONG wait_option)
11936 {
11937 
11938 UINT status;
11939 
11940     if ((ppp_ptr == NX_NULL) || (data_ptr == NX_NULL))
11941     {
11942         return NX_PTR_ERROR;
11943     }
11944 
11945     if (data_size == 0)
11946     {
11947         return NX_PPP_INVALID_PARAMETER;
11948     }
11949 
11950     status = _nx_ppp_ping_request(ppp_ptr, data_ptr, data_size, wait_option);
11951 
11952     return status;
11953 
11954 }
11955 
11956 /**************************************************************************/
11957 /*                                                                        */
11958 /*  FUNCTION                                               RELEASE        */
11959 /*                                                                        */
11960 /*    _nx_ppp_ping_request                                PORTABLE C      */
11961 /*                                                           6.1          */
11962 /*  AUTHOR                                                                */
11963 /*                                                                        */
11964 /*    Yuxin Zhou, Microsoft Corporation                                   */
11965 /*                                                                        */
11966 /*  DESCRIPTION                                                           */
11967 /*                                                                        */
11968 /*    This function builds and sends an LCP echo request, and sets the    */
11969 /*    echo ID to the PPP nx_ppp_transmit_id. The caller waits for the echo*/
11970 /*    ID (nx_ppp_lcp_echo_reply_id) to be reset to zero to indicate a     */
11971 /*    matching echo reply was received.                                   */
11972 /*                                                                        */
11973 /*  INPUT                                                                 */
11974 /*                                                                        */
11975 /*    ppp_ptr                               PPP instance pointer          */
11976 /*    data_ptr                              Pointer to data in LCP echo   */
11977 /*    data_size                             Size of data in LCP echo      */
11978 /*    wait_option                           Wait option to transmit echo  */
11979 /*                                                                        */
11980 /*  OUTPUT                                                                */
11981 /*                                                                        */
11982 /*    NX_SUCCESS                            Echo request successfully sent*/
11983 /*    status                                Actual completion status      */
11984 /*                                                                        */
11985 /*  CALLS                                                                 */
11986 /*                                                                        */
11987 /*    nx_packet_allocate                    Allocate a packet for sending */
11988 /*    _nx_ppp_packet_transmit               Send PPP packet               */
11989 /*                                                                        */
11990 /*  CALLED BY                                                             */
11991 /*                                                                        */
11992 /*    Application code                                                    */
11993 /*                                                                        */
11994 /*  RELEASE HISTORY                                                       */
11995 /*                                                                        */
11996 /*    DATE              NAME                      DESCRIPTION             */
11997 /*                                                                        */
11998 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
11999 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12000 /*                                            resulting in version 6.1    */
12001 /*                                                                        */
12002 /**************************************************************************/
_nx_ppp_ping_request(NX_PPP * ppp_ptr,CHAR * data_ptr,ULONG data_size,ULONG wait_option)12003 UINT  _nx_ppp_ping_request(NX_PPP *ppp_ptr, CHAR *data_ptr, ULONG data_size, ULONG wait_option)
12004 {
12005 
12006 UINT        status;
12007 UINT        i;
12008 CHAR        *work_ptr;
12009 NX_PACKET   *packet_ptr;
12010 
12011 
12012     /* Echo request may only be sent in the LCP completed state..  */
12013     if (ppp_ptr -> nx_ppp_lcp_state !=  NX_PPP_LCP_COMPLETED_STATE)
12014     {
12015 
12016          return NX_PPP_NOT_ESTABLISHED;
12017     }
12018 
12019     /* Allocate a packet for the PPP packet.  */
12020     status =  nx_packet_allocate(ppp_ptr -> nx_ppp_packet_pool_ptr, &packet_ptr, NX_PPP_PACKET, wait_option);
12021 
12022     /* Determine if the packet was allocated successfully.  */
12023     if (status != NX_SUCCESS)
12024     {
12025 
12026         /* An error was detected, simply return a NULL pointer.  */
12027         return status;
12028     }
12029 
12030     /* Check if out of boundary.  */
12031     if ((UINT)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_prepend_ptr) < (UINT)(data_size + 10))
12032      {
12033 
12034         /* Release the packet.  */
12035         nx_packet_release(packet_ptr);
12036         return(NX_PPP_BAD_PACKET);
12037     }
12038 
12039     /* Increment the transmit ID.  */
12040     ppp_ptr -> nx_ppp_transmit_id++;
12041 
12042     /* Build the configuration request.  */
12043     packet_ptr -> nx_packet_prepend_ptr[0] =  (NX_PPP_LCP_PROTOCOL & 0xFF00) >> 8;
12044     packet_ptr -> nx_packet_prepend_ptr[1] =  NX_PPP_LCP_PROTOCOL & 0xFF;
12045     packet_ptr -> nx_packet_prepend_ptr[2] =  NX_PPP_LCP_ECHO_REQUEST;
12046     packet_ptr -> nx_packet_prepend_ptr[3] =  ppp_ptr -> nx_ppp_transmit_id;
12047 
12048     /* Indicate the PPP instance is waiting on an ECHO reply with this id: */
12049     ppp_ptr -> nx_ppp_lcp_echo_reply_id = ppp_ptr -> nx_ppp_transmit_id;
12050 
12051     /* Set up the length.  */
12052     packet_ptr -> nx_packet_prepend_ptr[4] =  (UCHAR)(((UINT)(data_size + 8)) >> 8);
12053     packet_ptr -> nx_packet_prepend_ptr[5] =  (UCHAR)(((UINT)(data_size + 8)) & 0xFF);
12054 
12055     /* Magic number will be all zeroes. */
12056     packet_ptr -> nx_packet_prepend_ptr[6] =   0;
12057     packet_ptr -> nx_packet_prepend_ptr[7] =  0;
12058     packet_ptr -> nx_packet_prepend_ptr[8] =  0;
12059     packet_ptr -> nx_packet_prepend_ptr[9] =  0;
12060 
12061     /* Load the data */
12062     work_ptr = data_ptr;
12063 
12064     /* Loop through the input buffer.  */
12065     for(i = 1; i <= data_size; i++)
12066     {
12067 
12068         /* Copy byte of IP address.  */
12069         packet_ptr -> nx_packet_prepend_ptr[i+9] =  (UCHAR)(*work_ptr);
12070         work_ptr++ ;
12071     }
12072 
12073     packet_ptr -> nx_packet_length =  i + 9;
12074     packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
12075 
12076 #ifndef NX_PPP_DISABLE_INFO
12077 
12078     /* Increment the number of LCP echo requests sent.  */
12079     ppp_ptr -> nx_ppp_lcp_echo_requests_sent++;
12080 
12081     /* Increment the number of LCP frames sent.  */
12082     ppp_ptr -> nx_ppp_lcp_frames_sent++;
12083 #endif
12084 
12085     /* Send the configure request packet.  */
12086     _nx_ppp_packet_transmit(ppp_ptr, packet_ptr);
12087 
12088     return NX_SUCCESS;
12089 }
12090 
12091 
12092 
12093 #ifdef NX_PPP_PPPOE_ENABLE
12094 /**************************************************************************/
12095 /*                                                                        */
12096 /*  FUNCTION                                               RELEASE        */
12097 /*                                                                        */
12098 /*    _nxe_ppp_packet_receive                             PORTABLE C      */
12099 /*                                                           6.1          */
12100 /*  AUTHOR                                                                */
12101 /*                                                                        */
12102 /*    Yuxin Zhou, Microsoft Corporation                                   */
12103 /*                                                                        */
12104 /*  DESCRIPTION                                                           */
12105 /*                                                                        */
12106 /*    This function checks for errors in the PPP packet receive           */
12107 /*    function call.                                                      */
12108 /*                                                                        */
12109 /*  INPUT                                                                 */
12110 /*                                                                        */
12111 /*    ppp_ptr                               Pointer to PPP instance       */
12112 /*    packet_ptr                            Pointer to packet to receive  */
12113 /*                                                                        */
12114 /*  OUTPUT                                                                */
12115 /*                                                                        */
12116 /*    status                                Completion status             */
12117 /*                                                                        */
12118 /*  CALLS                                                                 */
12119 /*                                                                        */
12120 /*    _nx_ppp_packet_receive                Actual PPP packet receive     */
12121 /*                                            function                    */
12122 /*                                                                        */
12123 /*  CALLED BY                                                             */
12124 /*                                                                        */
12125 /*    Application Code                                                    */
12126 /*                                                                        */
12127 /*  RELEASE HISTORY                                                       */
12128 /*                                                                        */
12129 /*    DATE              NAME                      DESCRIPTION             */
12130 /*                                                                        */
12131 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12132 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12133 /*                                            resulting in version 6.1    */
12134 /*                                                                        */
12135 /**************************************************************************/
_nxe_ppp_packet_receive(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)12136 UINT  _nxe_ppp_packet_receive(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
12137 {
12138 
12139 UINT    status;
12140 
12141 
12142     /* Check for an invalid input pointer.  */
12143     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
12144         return(NX_PTR_ERROR);
12145 
12146     /* Check for packet pointer.  */
12147     if (packet_ptr == NX_NULL)
12148         return(NX_PTR_ERROR);
12149 
12150     /* Call actual packet receive function.  */
12151     status =  _nx_ppp_packet_receive(ppp_ptr, packet_ptr);
12152 
12153     /* Return completion status.  */
12154     return(status);
12155 }
12156 
12157 
12158 /**************************************************************************/
12159 /*                                                                        */
12160 /*  FUNCTION                                               RELEASE        */
12161 /*                                                                        */
12162 /*    _nx_ppp_packet_receive                              PORTABLE C      */
12163 /*                                                           6.1          */
12164 /*  AUTHOR                                                                */
12165 /*                                                                        */
12166 /*    Yuxin Zhou, Microsoft Corporation                                   */
12167 /*                                                                        */
12168 /*  DESCRIPTION                                                           */
12169 /*                                                                        */
12170 /*    This function receives packet from the application (usually an      */
12171 /*    application ISR), buffers it, and notifies the PPP receive thread.  */
12172 /*                                                                        */
12173 /*  INPUT                                                                 */
12174 /*                                                                        */
12175 /*    ppp_ptr                               Pointer to PPP instance       */
12176 /*    packet_ptr                            Pointer to packet to receive  */
12177 /*                                                                        */
12178 /*  OUTPUT                                                                */
12179 /*                                                                        */
12180 /*    status                                Completion status             */
12181 /*                                                                        */
12182 /*  CALLS                                                                 */
12183 /*                                                                        */
12184 /*    tx_event_flags_set                    Notify PPP receiving thread   */
12185 /*                                                                        */
12186 /*  CALLED BY                                                             */
12187 /*                                                                        */
12188 /*    Application Code (Including ISRs)                                   */
12189 /*                                                                        */
12190 /*  RELEASE HISTORY                                                       */
12191 /*                                                                        */
12192 /*    DATE              NAME                      DESCRIPTION             */
12193 /*                                                                        */
12194 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12195 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12196 /*                                            resulting in version 6.1    */
12197 /*                                                                        */
12198 /**************************************************************************/
_nx_ppp_packet_receive(NX_PPP * ppp_ptr,NX_PACKET * packet_ptr)12199 UINT  _nx_ppp_packet_receive(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr)
12200 {
12201 
12202 TX_INTERRUPT_SAVE_AREA
12203 
12204     /* Disable interrupts.  */
12205     TX_DISABLE
12206 
12207     /* Check for no longer active PPP instance.  */
12208     if (ppp_ptr -> nx_ppp_id != NX_PPP_ID)
12209     {
12210 
12211         /* PPP is no longer active.  */
12212 
12213         /* Restore interrupts.  */
12214         TX_RESTORE
12215 
12216         /* Return an error.  */
12217         return(NX_PTR_ERROR);
12218     }
12219 
12220     /* Check for a stopped PPP instance.  */
12221     if (ppp_ptr -> nx_ppp_state == NX_PPP_STOPPED)
12222     {
12223 
12224         /* Silently discard byte.  */
12225 
12226         /* Restore interrupts.  */
12227         TX_RESTORE
12228 
12229         /* Return success.  */
12230         return(NX_SUCCESS);
12231     }
12232 
12233     /* Check to see if the deferred processing queue is empty.  */
12234     if (ppp_ptr -> nx_ppp_deferred_received_packet_head)
12235     {
12236 
12237         /* Not empty, just place the packet at the end of the queue.  */
12238         (ppp_ptr -> nx_ppp_deferred_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
12239         packet_ptr -> nx_packet_queue_next =  NX_NULL;
12240         ppp_ptr -> nx_ppp_deferred_received_packet_tail = packet_ptr;
12241 
12242         /* Restore interrupts.  */
12243         TX_RESTORE
12244     }
12245     else
12246     {
12247 
12248         /* Empty deferred receive processing queue.  Just setup the head pointers and
12249            set the event flags to ensure the PPP helper thread looks at the deferred processing
12250            queue.  */
12251         ppp_ptr -> nx_ppp_deferred_received_packet_head = packet_ptr;
12252         ppp_ptr -> nx_ppp_deferred_received_packet_tail = packet_ptr;
12253         packet_ptr -> nx_packet_queue_next = NX_NULL;
12254 
12255         /* Restore interrupts.  */
12256         TX_RESTORE
12257 
12258         /* Wakeup PPP helper thread to process the PPP deferred receive.  */
12259         tx_event_flags_set(&(ppp_ptr -> nx_ppp_event), NX_PPP_EVENT_PPPOE_PACKET_RECEIVE, TX_OR);
12260     }
12261 
12262     /* Return successful completion.  */
12263     return(NX_SUCCESS);
12264 }
12265 
12266 
12267 /**************************************************************************/
12268 /*                                                                        */
12269 /*  FUNCTION                                               RELEASE        */
12270 /*                                                                        */
12271 /*    _nxe_ppp_packet_send_set                            PORTABLE C      */
12272 /*                                                           6.1          */
12273 /*  AUTHOR                                                                */
12274 /*                                                                        */
12275 /*    Yuxin Zhou, Microsoft Corporation                                   */
12276 /*                                                                        */
12277 /*  DESCRIPTION                                                           */
12278 /*                                                                        */
12279 /*    This function checks for errors in the PPP set packet send          */
12280 /*    function call.                                                      */
12281 /*                                                                        */
12282 /*  INPUT                                                                 */
12283 /*                                                                        */
12284 /*    ppp_ptr                               Pointer to PPP instance       */
12285 /*    nx_ppp_packet_send                    Routine to send PPP packet    */
12286 /*                                                                        */
12287 /*  OUTPUT                                                                */
12288 /*                                                                        */
12289 /*    status                                Completion status             */
12290 /*                                                                        */
12291 /*  CALLS                                                                 */
12292 /*                                                                        */
12293 /*    _nxe_ppp_packet_send_set              Actual PPP packet send set    */
12294 /*                                            function                    */
12295 /*                                                                        */
12296 /*  CALLED BY                                                             */
12297 /*                                                                        */
12298 /*    Application Code                                                    */
12299 /*                                                                        */
12300 /*  RELEASE HISTORY                                                       */
12301 /*                                                                        */
12302 /*    DATE              NAME                      DESCRIPTION             */
12303 /*                                                                        */
12304 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12305 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12306 /*                                            resulting in version 6.1    */
12307 /*                                                                        */
12308 /**************************************************************************/
_nxe_ppp_packet_send_set(NX_PPP * ppp_ptr,VOID (* nx_ppp_packet_send)(NX_PACKET * packet_ptr))12309 UINT  _nxe_ppp_packet_send_set(NX_PPP *ppp_ptr, VOID (*nx_ppp_packet_send)(NX_PACKET *packet_ptr))
12310 {
12311 
12312 UINT    status;
12313 
12314 
12315     /* Check for an invalid input pointer.  */
12316     if ((ppp_ptr == NX_NULL) || (ppp_ptr -> nx_ppp_id != NX_PPP_ID))
12317         return(NX_PTR_ERROR);
12318 
12319     /* Check for packet pointer.  */
12320     if (nx_ppp_packet_send == NX_NULL)
12321         return(NX_PTR_ERROR);
12322 
12323     /* Call actual packet send set function.  */
12324     status =  _nx_ppp_packet_send_set(ppp_ptr, nx_ppp_packet_send);
12325 
12326     /* Return completion status.  */
12327     return(status);
12328 }
12329 
12330 
12331 /**************************************************************************/
12332 /*                                                                        */
12333 /*  FUNCTION                                               RELEASE        */
12334 /*                                                                        */
12335 /*    _nx_ppp_packet_send_set                             PORTABLE C      */
12336 /*                                                           6.1          */
12337 /*  AUTHOR                                                                */
12338 /*                                                                        */
12339 /*    Yuxin Zhou, Microsoft Corporation                                   */
12340 /*                                                                        */
12341 /*  DESCRIPTION                                                           */
12342 /*                                                                        */
12343 /*    This function set the PPP packet send function.                     */
12344 /*                                                                        */
12345 /*  INPUT                                                                 */
12346 /*                                                                        */
12347 /*    ppp_ptr                               Pointer to PPP instance       */
12348 /*    nx_ppp_packet_send                    Routine to send PPP packet    */
12349 /*                                                                        */
12350 /*  OUTPUT                                                                */
12351 /*                                                                        */
12352 /*    status                                Completion status             */
12353 /*                                                                        */
12354 /*  CALLS                                                                 */
12355 /*                                                                        */
12356 /*    none                                                                */
12357 /*                                                                        */
12358 /*  CALLED BY                                                             */
12359 /*                                                                        */
12360 /*    Application Code                                                    */
12361 /*                                                                        */
12362 /*  RELEASE HISTORY                                                       */
12363 /*                                                                        */
12364 /*    DATE              NAME                      DESCRIPTION             */
12365 /*                                                                        */
12366 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
12367 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
12368 /*                                            resulting in version 6.1    */
12369 /*                                                                        */
12370 /**************************************************************************/
_nx_ppp_packet_send_set(NX_PPP * ppp_ptr,VOID (* nx_ppp_packet_send)(NX_PACKET * packet_ptr))12371 UINT  _nx_ppp_packet_send_set(NX_PPP *ppp_ptr, VOID (*nx_ppp_packet_send)(NX_PACKET *packet_ptr))
12372 {
12373 
12374 
12375     /* Set the PPP packet send function.  */
12376     ppp_ptr -> nx_ppp_packet_send = nx_ppp_packet_send;
12377 
12378     /* Return successful completion.  */
12379     return(NX_SUCCESS);
12380 }
12381 #endif /*  NX_PPP_PPPOE_ENABLE  */
12382 #endif /* NX_DISABLE_IPV4 */
12383