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