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