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