1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Component                                                        */
16 /**                                                                       */
17 /**   PPP Over Ethernet (PPPoE)                                           */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_PPPOE_CLIENT_SOURCE_CODE
23 
24 
25 /* Force error checking to be disabled in this module */
26 #include "tx_port.h"
27 
28 #ifndef NX_DISABLE_ERROR_CHECKING
29 #define NX_DISABLE_ERROR_CHECKING
30 #endif
31 
32 #ifndef TX_SAFETY_CRITICAL
33 #ifndef TX_DISABLE_ERROR_CHECKING
34 #define TX_DISABLE_ERROR_CHECKING
35 #endif
36 #endif
37 
38 
39 /* Include necessary system files.  */
40 
41 #include "nx_api.h"
42 #ifndef NX_DISABLE_IPV4
43 #include "nx_ip.h"
44 #include "nx_packet.h"
45 #include "nx_pppoe_client.h"
46 #include "tx_thread.h"
47 #include "tx_timer.h"
48 
49 /* Define the PPPoE created list head pointer and count.  */
50 NX_PPPOE_CLIENT  *_nx_pppoe_client_created_ptr = NX_NULL;
51 
52 
53 /* Define internal PPPoE services. */
54 
55 static VOID    _nx_pppoe_client_thread_entry(ULONG pppoe_client_ptr_value);
56 static VOID    _nx_pppoe_client_timer_entry(ULONG pppoe_client_address);
57 static VOID    _nx_pppoe_client_packet_receive(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr);
58 static VOID    _nx_pppoe_client_discovery_packet_process(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr, ULONG server_mac_msw, ULONG server_mac_lsw);
59 static VOID    _nx_pppoe_client_session_packet_process(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr, ULONG server_mac_msw, ULONG server_mac_lsw);
60 static UINT    _nx_pppoe_client_discovery_send(NX_PPPOE_CLIENT *pppoe_client_ptr, UINT code);
61 static VOID    _nx_pppoe_client_packet_send(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr, UINT command);
62 static ULONG   _nx_pppoe_client_data_get(UCHAR *data, UINT size);
63 static VOID    _nx_pppoe_client_data_add(UCHAR *data, UINT size, ULONG value);
64 static VOID    _nx_pppoe_client_string_add(UCHAR *dest, UCHAR *source, UINT size);
65 static UINT    _nx_pppoe_client_tag_string_add(UCHAR *data_ptr, UINT tag_type, UINT tag_length,  UCHAR *tag_value_string, UINT *index);
66 static UINT    _nx_pppoe_client_session_cleanup(NX_PPPOE_CLIENT *pppoe_client_ptr);
67 static VOID    _nx_pppoe_client_session_connect_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER);
68 static VOID    _nx_pppoe_client_session_thread_resume(TX_THREAD **suspension_list_head, UINT status);
69 static VOID    _nx_pppoe_client_session_thread_suspend(TX_THREAD **suspension_list_head, VOID (*suspend_cleanup)(TX_THREAD * NX_CLEANUP_PARAMETER),
70                                                      NX_PPPOE_CLIENT *pppoe_client_ptr, TX_MUTEX *mutex_ptr, ULONG wait_option);
71 
72 
73 /**************************************************************************/
74 /*                                                                        */
75 /*  FUNCTION                                               RELEASE        */
76 /*                                                                        */
77 /*    _nxe_pppoe_client_create                            PORTABLE C      */
78 /*                                                           6.1          */
79 /*  AUTHOR                                                                */
80 /*                                                                        */
81 /*    Yuxin Zhou, Microsoft Corporation                                   */
82 /*                                                                        */
83 /*  DESCRIPTION                                                           */
84 /*                                                                        */
85 /*    This function checks for errors in the PPPoE Client instance create */
86 /*    function call.                                                      */
87 /*                                                                        */
88 /*  INPUT                                                                 */
89 /*                                                                        */
90 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
91 /*    name                                  Name of this PPPoE instance   */
92 /*    ip_ptr                                Pointer to IP control block   */
93 /*    interface_index                       IP Interface Index            */
94 /*    pool_ptr                              packet pool                   */
95 /*    stack_ptr                             Pointer stack area for PPPoE  */
96 /*    stack_size                            Size of PPPoE stack area      */
97 /*    priority                              Priority of PPPoE  thread     */
98 /*    pppoe_link_driver                     User supplied link driver     */
99 /*    pppoe_packet_receive                  User supplied function to     */
100 /*                                            receive PPPoE packet        */
101 /*                                                                        */
102 /*  OUTPUT                                                                */
103 /*                                                                        */
104 /*    status                                Completion status             */
105 /*                                                                        */
106 /*  CALLS                                                                 */
107 /*                                                                        */
108 /*    _nx_pppoe_client_create               Actual PPPoE instance create  */
109 /*                                            function                    */
110 /*                                                                        */
111 /*  CALLED BY                                                             */
112 /*                                                                        */
113 /*    Application                                                         */
114 /*                                                                        */
115 /*  RELEASE HISTORY                                                       */
116 /*                                                                        */
117 /*    DATE              NAME                      DESCRIPTION             */
118 /*                                                                        */
119 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
120 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
121 /*                                            resulting in version 6.1    */
122 /*                                                                        */
123 /**************************************************************************/
_nxe_pppoe_client_create(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * name,NX_IP * ip_ptr,UINT interface_index,NX_PACKET_POOL * pool_ptr,VOID * stack_ptr,ULONG stack_size,UINT priority,VOID (* pppoe_link_driver)(struct NX_IP_DRIVER_STRUCT *),VOID (* pppoe_packet_receive)(NX_PACKET * packet_ptr))124 UINT  _nxe_pppoe_client_create(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *name, NX_IP *ip_ptr, UINT interface_index,
125                                NX_PACKET_POOL *pool_ptr, VOID *stack_ptr, ULONG stack_size, UINT priority,
126                                VOID (*pppoe_link_driver)(struct NX_IP_DRIVER_STRUCT *),
127                                VOID (*pppoe_packet_receive)(NX_PACKET *packet_ptr))
128 {
129 
130 UINT    status;
131 
132     /* Check for invalid input pointers.  */
133     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id == NX_PPPOE_CLIENT_ID) ||
134         (ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
135         (pool_ptr == NX_NULL) || (pool_ptr -> nx_packet_pool_id != NX_PACKET_POOL_ID) ||
136         (stack_ptr == NX_NULL) || (pppoe_link_driver == NX_NULL) || (pppoe_packet_receive == NX_NULL))
137         return(NX_PPPOE_CLIENT_PTR_ERROR);
138 
139     /* Check for invalid interface ID */
140     if(interface_index >= NX_MAX_PHYSICAL_INTERFACES)
141         return(NX_PPPOE_CLIENT_INVALID_INTERFACE);
142 
143     /* Check for interface being valid. */
144     if(!ip_ptr -> nx_ip_interface[interface_index].nx_interface_valid)
145         return(NX_PPPOE_CLIENT_INVALID_INTERFACE);
146 
147     /* Check for payload size of packet pool.  */
148     if (pool_ptr -> nx_packet_pool_payload_size < NX_PPPOE_CLIENT_MIN_PACKET_PAYLOAD_SIZE)
149         return(NX_PPPOE_CLIENT_PACKET_PAYLOAD_ERROR);
150 
151     /* Check for a memory size error.  */
152     if (stack_size < TX_MINIMUM_STACK)
153         return(NX_PPPOE_CLIENT_MEMORY_SIZE_ERROR);
154 
155     /* Check the priority specified.  */
156     if (priority >= TX_MAX_PRIORITIES)
157         return(NX_PPPOE_CLIENT_PRIORITY_ERROR);
158 
159     /* Call actual PPPoE client instance create function.  */
160     status =  _nx_pppoe_client_create(pppoe_client_ptr, name, ip_ptr, interface_index,
161                                       pool_ptr, stack_ptr, stack_size, priority,
162                                       pppoe_link_driver, pppoe_packet_receive);
163 
164     /* Return completion status.  */
165     return(status);
166 }
167 
168 
169 /**************************************************************************/
170 /*                                                                        */
171 /*  FUNCTION                                               RELEASE        */
172 /*                                                                        */
173 /*    _nx_pppoe_client_create                             PORTABLE C      */
174 /*                                                           6.1          */
175 /*  AUTHOR                                                                */
176 /*                                                                        */
177 /*    Yuxin Zhou, Microsoft Corporation                                   */
178 /*                                                                        */
179 /*  DESCRIPTION                                                           */
180 /*                                                                        */
181 /*    This function creates an PPPoE Client instance, including setting   */
182 /*    up all appropriate data structures, creating PPPoE event flag       */
183 /*    object and PPPoE thread.                                            */
184 /*                                                                        */
185 /*  INPUT                                                                 */
186 /*                                                                        */
187 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
188 /*    name                                  Name of this PPPoE instance   */
189 /*    ip_ptr                                Pointer to IP control block   */
190 /*    interface_index                       Interface Index               */
191 /*    pool_ptr                              packet pool                   */
192 /*    stack_ptr                             Pointer stack area for PPPoE  */
193 /*    stack_size                            Size of PPPoE stack area      */
194 /*    priority                              Priority of PPPoE  thread     */
195 /*    pppoe_link_driver                     User supplied link driver     */
196 /*    pppoe_packet_receive                  User supplied function to     */
197 /*                                            receive PPPoE packet        */
198 /*                                                                        */
199 /*  OUTPUT                                                                */
200 /*                                                                        */
201 /*    status                                Completion status             */
202 /*                                                                        */
203 /*  CALLS                                                                 */
204 /*                                                                        */
205 /*    tx_event_flags_create                 Create IP event flags         */
206 /*    tx_thread_create                      Create IP helper thread       */
207 /*                                                                        */
208 /*  CALLED BY                                                             */
209 /*                                                                        */
210 /*    Application                                                         */
211 /*                                                                        */
212 /*  RELEASE HISTORY                                                       */
213 /*                                                                        */
214 /*    DATE              NAME                      DESCRIPTION             */
215 /*                                                                        */
216 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
217 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
218 /*                                            resulting in version 6.1    */
219 /*                                                                        */
220 /**************************************************************************/
_nx_pppoe_client_create(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * name,NX_IP * ip_ptr,UINT interface_index,NX_PACKET_POOL * pool_ptr,VOID * stack_ptr,ULONG stack_size,UINT priority,VOID (* pppoe_link_driver)(struct NX_IP_DRIVER_STRUCT *),VOID (* pppoe_packet_receive)(NX_PACKET * packet_ptr))221 UINT  _nx_pppoe_client_create(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *name, NX_IP *ip_ptr, UINT interface_index,
222                               NX_PACKET_POOL *pool_ptr, VOID *stack_ptr, ULONG stack_size, UINT priority,
223                               VOID (*pppoe_link_driver)(struct NX_IP_DRIVER_STRUCT *),
224                               VOID (*pppoe_packet_receive)(NX_PACKET *packet_ptr))
225 {
226 
227 TX_INTERRUPT_SAVE_AREA
228 
229 
230     /* Initialize the PPPoE Server control block to zero.  */
231     memset((void *) pppoe_client_ptr, 0, sizeof(NX_PPPOE_CLIENT));
232 
233     /* Save the PPPoE name.  */
234     pppoe_client_ptr -> nx_pppoe_name = name;
235 
236     /* Save the IP pointer.  */
237     pppoe_client_ptr -> nx_pppoe_ip_ptr = ip_ptr;
238 
239     /* Setup the interface index and interface pointer.  */
240     pppoe_client_ptr -> nx_pppoe_interface_ptr = &(ip_ptr -> nx_ip_interface[interface_index]);
241 
242     /* Save the packet pool pointer.  */
243     pppoe_client_ptr -> nx_pppoe_packet_pool_ptr = pool_ptr;
244 
245     /* Setup the link driver address.  */
246     pppoe_client_ptr -> nx_pppoe_link_driver_entry = pppoe_link_driver;
247 
248     /* Setup the function to receive PPPoE packet.  */
249     pppoe_client_ptr ->nx_pppoe_packet_receive = pppoe_packet_receive;
250 
251     /* Create event flag group to control the PPPoE processing thread.  */
252     tx_event_flags_create(&(pppoe_client_ptr -> nx_pppoe_events), "PPPoE Client EVENTS") ;
253 
254     /* Create the PPPoE processing thread.  */
255     tx_thread_create(&(pppoe_client_ptr -> nx_pppoe_thread), "PPPoE Client THREAD", _nx_pppoe_client_thread_entry, (ULONG) pppoe_client_ptr,
256                      stack_ptr, stack_size, priority, priority, NX_PPPOE_CLIENT_THREAD_TIME_SLICE, TX_AUTO_START);
257 
258     /* Create the PPPoE timer.  */
259     tx_timer_create(&(pppoe_client_ptr -> nx_pppoe_timer), "PPPoE Client timer",
260                     (VOID (*)(ULONG))_nx_pppoe_client_timer_entry, (ULONG)pppoe_client_ptr,
261                     NX_IP_PERIODIC_RATE, NX_IP_PERIODIC_RATE, TX_NO_ACTIVATE);
262 
263     /* Otherwise, the PPPoE initialization was successful.  Place the
264        PPPoE control block on created PPPoE instance.  */
265     TX_DISABLE
266 
267     /* Load the PPPoE Client ID field in the PPPoE Client control block.  */
268     pppoe_client_ptr -> nx_pppoe_id =  NX_PPPOE_CLIENT_ID;
269 
270     /* Set the pointer of global variable PPPoE.  */
271     _nx_pppoe_client_created_ptr = pppoe_client_ptr;
272 
273     /* Restore previous interrupt posture.  */
274     TX_RESTORE
275 
276     /* Return success.  */
277     return(NX_PPPOE_CLIENT_SUCCESS);
278 }
279 
280 
281 /**************************************************************************/
282 /*                                                                        */
283 /*  FUNCTION                                               RELEASE        */
284 /*                                                                        */
285 /*    _nxe_pppoe_client_delete                            PORTABLE C      */
286 /*                                                           6.1          */
287 /*  AUTHOR                                                                */
288 /*                                                                        */
289 /*    Yuxin Zhou, Microsoft Corporation                                   */
290 /*                                                                        */
291 /*  DESCRIPTION                                                           */
292 /*                                                                        */
293 /*    This function checks for errors in the PPPoE Client instance delete */
294 /*    function call.                                                      */
295 /*                                                                        */
296 /*  INPUT                                                                 */
297 /*                                                                        */
298 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
299 /*                                                                        */
300 /*  OUTPUT                                                                */
301 /*                                                                        */
302 /*    status                                Completion status             */
303 /*                                                                        */
304 /*  CALLS                                                                 */
305 /*                                                                        */
306 /*    _nx_pppoe_client_delete               Actual PPPoE instance delete  */
307 /*                                            function                    */
308 /*                                                                        */
309 /*  CALLED BY                                                             */
310 /*                                                                        */
311 /*    Application                                                         */
312 /*                                                                        */
313 /*  RELEASE HISTORY                                                       */
314 /*                                                                        */
315 /*    DATE              NAME                      DESCRIPTION             */
316 /*                                                                        */
317 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
318 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
319 /*                                            resulting in version 6.1    */
320 /*                                                                        */
321 /**************************************************************************/
_nxe_pppoe_client_delete(NX_PPPOE_CLIENT * pppoe_client_ptr)322 UINT  _nxe_pppoe_client_delete(NX_PPPOE_CLIENT *pppoe_client_ptr)
323 {
324 
325 UINT    status;
326 
327     /* Check for invalid input pointers.  */
328     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
329         return(NX_PPPOE_CLIENT_PTR_ERROR);
330 
331     /* Call actual PPPoE client instance delete function.  */
332     status =  _nx_pppoe_client_delete(pppoe_client_ptr);
333 
334     /* Return completion status.  */
335     return(status);
336 }
337 
338 
339 /**************************************************************************/
340 /*                                                                        */
341 /*  FUNCTION                                               RELEASE        */
342 /*                                                                        */
343 /*    _nx_pppoe_client_delete                             PORTABLE C      */
344 /*                                                           6.1          */
345 /*  AUTHOR                                                                */
346 /*                                                                        */
347 /*    Yuxin Zhou, Microsoft Corporation                                   */
348 /*                                                                        */
349 /*  DESCRIPTION                                                           */
350 /*                                                                        */
351 /*    This function deletes an PPPoE Client instance. including deleting  */
352 /*    PPPoE event flag object and PPPoE thread.                           */
353 /*                                                                        */
354 /*  INPUT                                                                 */
355 /*                                                                        */
356 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
357 /*                                                                        */
358 /*  OUTPUT                                                                */
359 /*                                                                        */
360 /*    status                                Completion status             */
361 /*                                                                        */
362 /*  CALLS                                                                 */
363 /*                                                                        */
364 /*    tx_thread_terminate                   Terminate PPPoE helper thread */
365 /*    tx_thread_delete                      Delete PPPoE helper thread    */
366 /*    tx_event_flags_delete                 Delete PPPoE event flags      */
367 /*                                                                        */
368 /*  CALLED BY                                                             */
369 /*                                                                        */
370 /*    Application                                                         */
371 /*                                                                        */
372 /*  RELEASE HISTORY                                                       */
373 /*                                                                        */
374 /*    DATE              NAME                      DESCRIPTION             */
375 /*                                                                        */
376 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
377 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
378 /*                                            resulting in version 6.1    */
379 /*                                                                        */
380 /**************************************************************************/
_nx_pppoe_client_delete(NX_PPPOE_CLIENT * pppoe_client_ptr)381 UINT  _nx_pppoe_client_delete(NX_PPPOE_CLIENT *pppoe_client_ptr)
382 {
383 
384 TX_INTERRUPT_SAVE_AREA
385 
386 
387     /* Determine if the caller is the PPPoE thread itself. This is not allowed since
388        a thread cannot delete itself in ThreadX.  */
389     if (&pppoe_client_ptr -> nx_pppoe_thread == tx_thread_identify())
390     {
391 
392         /* Invalid caller of this routine, return an error!  */
393         return(NX_CALLER_ERROR);
394     }
395 
396     /* Disable interrupts.  */
397     TX_DISABLE
398 
399     /* Clear the PPPOE ID to show that it is no longer valid.  */
400     pppoe_client_ptr -> nx_pppoe_id = 0;
401 
402     /* Clear the created pointer.  */
403     _nx_pppoe_client_created_ptr = NX_NULL;
404 
405     /* Restore previous interrupt posture.  */
406     TX_RESTORE
407 
408     /* Terminate the thread.  */
409     tx_thread_terminate(&(pppoe_client_ptr -> nx_pppoe_thread));
410 
411     /* Delete the PPPoE thread.  */
412     tx_thread_delete(&(pppoe_client_ptr -> nx_pppoe_thread));
413 
414     /* Delete the event flag group.  */
415     tx_event_flags_delete(&(pppoe_client_ptr -> nx_pppoe_events));
416 
417     /* Return success.  */
418     return(NX_PPPOE_CLIENT_SUCCESS);
419 }
420 
421 
422 /**************************************************************************/
423 /*                                                                        */
424 /*  FUNCTION                                               RELEASE        */
425 /*                                                                        */
426 /*    _nxe_pppoe_client_service_name_set                  PORTABLE C      */
427 /*                                                           6.1          */
428 /*  AUTHOR                                                                */
429 /*                                                                        */
430 /*    Yuxin Zhou, Microsoft Corporation                                   */
431 /*                                                                        */
432 /*  DESCRIPTION                                                           */
433 /*                                                                        */
434 /*    This function checks for errors in the PPPoE service name set       */
435 /*    function call.                                                      */
436 /*                                                                        */
437 /*  INPUT                                                                 */
438 /*                                                                        */
439 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
440 /*    service_name                          Pointer to an service name.   */
441 /*                                            Service name must be        */
442 /*                                            Null-terminated string.     */
443 /*                                                                        */
444 /*  OUTPUT                                                                */
445 /*                                                                        */
446 /*    status                                Completion status             */
447 /*                                                                        */
448 /*  CALLS                                                                 */
449 /*                                                                        */
450 /*    _nx_pppoe_client_service_name_set     Actual PPPoE service name set */
451 /*                                            function                    */
452 /*                                                                        */
453 /*  CALLED BY                                                             */
454 /*                                                                        */
455 /*    Application                                                         */
456 /*                                                                        */
457 /*  RELEASE HISTORY                                                       */
458 /*                                                                        */
459 /*    DATE              NAME                      DESCRIPTION             */
460 /*                                                                        */
461 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
462 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
463 /*                                            resulting in version 6.1    */
464 /*                                                                        */
465 /**************************************************************************/
_nxe_pppoe_client_service_name_set(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * service_name)466 UINT  _nxe_pppoe_client_service_name_set(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *service_name)
467 {
468 
469 UINT    status;
470 
471     /* Check for invalid input pointers.  */
472     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
473         return(NX_PPPOE_CLIENT_PTR_ERROR);
474 
475     /* Call actual PPPoE service name set function.  */
476     status =  _nx_pppoe_client_service_name_set(pppoe_client_ptr, service_name);
477 
478     /* Return completion status.  */
479     return(status);
480 }
481 
482 
483 /**************************************************************************/
484 /*                                                                        */
485 /*  FUNCTION                                               RELEASE        */
486 /*                                                                        */
487 /*    _nx_pppoe_client_service_name_set                   PORTABLE C      */
488 /*                                                           6.1          */
489 /*  AUTHOR                                                                */
490 /*                                                                        */
491 /*    Yuxin Zhou, Microsoft Corporation                                   */
492 /*                                                                        */
493 /*  DESCRIPTION                                                           */
494 /*                                                                        */
495 /*    This function sets the service name for PPPoE Client.               */
496 /*                                                                        */
497 /*  INPUT                                                                 */
498 /*                                                                        */
499 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
500 /*    service_name                          Pointer to an service name.   */
501 /*                                            Service name must be        */
502 /*                                            Null-terminated string.     */
503 /*                                                                        */
504 /*  OUTPUT                                                                */
505 /*                                                                        */
506 /*    status                                Completion status             */
507 /*                                                                        */
508 /*  CALLS                                                                 */
509 /*                                                                        */
510 /*    _nx_utility_string_length_check       Check string length           */
511 /*    _nx_pppoe_client_service_name_set     Actual PPPoE service name set */
512 /*                                          function                      */
513 /*                                                                        */
514 /*  CALLED BY                                                             */
515 /*                                                                        */
516 /*    Application                                                         */
517 /*                                                                        */
518 /*  RELEASE HISTORY                                                       */
519 /*                                                                        */
520 /*    DATE              NAME                      DESCRIPTION             */
521 /*                                                                        */
522 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
523 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
524 /*                                            resulting in version 6.1    */
525 /*                                                                        */
526 /**************************************************************************/
_nx_pppoe_client_service_name_set(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * service_name)527 UINT  _nx_pppoe_client_service_name_set(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *service_name)
528 {
529 UINT status;
530 UINT service_name_length = 0;
531 
532 
533     /* Calculate the service_name length.  */
534     if (_nx_utility_string_length_check((CHAR *)service_name, &service_name_length, NX_MAX_STRING_LENGTH))
535     {
536         return(NX_SIZE_ERROR);
537     }
538 
539     /* Call actual PPPoE service name set function.  */
540     status =  _nx_pppoe_client_service_name_set_extended(pppoe_client_ptr, service_name, service_name_length);
541 
542     /* Return completion status.  */
543     return(status);
544 }
545 
546 /**************************************************************************/
547 /*                                                                        */
548 /*  FUNCTION                                               RELEASE        */
549 /*                                                                        */
550 /*    _nxe_pppoe_client_service_name_set_extended         PORTABLE C      */
551 /*                                                           6.1          */
552 /*  AUTHOR                                                                */
553 /*                                                                        */
554 /*    Yuxin Zhou, Microsoft Corporation                                   */
555 /*                                                                        */
556 /*  DESCRIPTION                                                           */
557 /*                                                                        */
558 /*    This function checks for errors in the PPPoE service name set       */
559 /*    function call.                                                      */
560 /*                                                                        */
561 /*  INPUT                                                                 */
562 /*                                                                        */
563 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
564 /*    service_name                          Pointer to an service name.   */
565 /*                                            Service name must be        */
566 /*                                            Null-terminated string.     */
567 /*    service_name_length                   Length of service_name        */
568 /*                                                                        */
569 /*  OUTPUT                                                                */
570 /*                                                                        */
571 /*    status                                Completion status             */
572 /*                                                                        */
573 /*  CALLS                                                                 */
574 /*                                                                        */
575 /*    _nx_pppoe_client_service_name_set_extended                          */
576 /*                                          Actual PPPoE service name set */
577 /*                                          function                      */
578 /*                                                                        */
579 /*  CALLED BY                                                             */
580 /*                                                                        */
581 /*    Application                                                         */
582 /*                                                                        */
583 /*  RELEASE HISTORY                                                       */
584 /*                                                                        */
585 /*    DATE              NAME                      DESCRIPTION             */
586 /*                                                                        */
587 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
588 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
589 /*                                            resulting in version 6.1    */
590 /*                                                                        */
591 /**************************************************************************/
_nxe_pppoe_client_service_name_set_extended(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * service_name,UINT service_name_length)592 UINT  _nxe_pppoe_client_service_name_set_extended(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *service_name, UINT service_name_length)
593 {
594 
595 UINT    status;
596 
597     /* Check for invalid input pointers.  */
598     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
599         return(NX_PPPOE_CLIENT_PTR_ERROR);
600 
601     /* Call actual PPPoE service name set function.  */
602     status =  _nx_pppoe_client_service_name_set_extended(pppoe_client_ptr, service_name, service_name_length);
603 
604     /* Return completion status.  */
605     return(status);
606 }
607 
608 
609 /**************************************************************************/
610 /*                                                                        */
611 /*  FUNCTION                                               RELEASE        */
612 /*                                                                        */
613 /*    _nx_pppoe_client_service_name_set_extended          PORTABLE C      */
614 /*                                                           6.1.3        */
615 /*  AUTHOR                                                                */
616 /*                                                                        */
617 /*    Yuxin Zhou, Microsoft Corporation                                   */
618 /*                                                                        */
619 /*  DESCRIPTION                                                           */
620 /*                                                                        */
621 /*    This function sets the service name for PPPoE Client.               */
622 /*                                                                        */
623 /*    Note: The string of service_name must be NULL-terminated and length */
624 /*    of service_name matches the length specified in the argument list.  */
625 /*                                                                        */
626 /*  INPUT                                                                 */
627 /*                                                                        */
628 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
629 /*    service_name                          Pointer to an service name.   */
630 /*                                            Service name must be        */
631 /*                                            Null-terminated string.     */
632 /*    service_name_length                   Length of service_name        */
633 /*                                                                        */
634 /*  OUTPUT                                                                */
635 /*                                                                        */
636 /*    status                                Completion status             */
637 /*                                                                        */
638 /*  CALLS                                                                 */
639 /*                                                                        */
640 /*    _nx_utility_string_length_check       Check string length           */
641 /*    tx_mutex_get                          Obtain a protection mutex     */
642 /*    tx_mutex_put                          Release protection mutex      */
643 /*                                                                        */
644 /*  CALLED BY                                                             */
645 /*                                                                        */
646 /*    Application                                                         */
647 /*                                                                        */
648 /*  RELEASE HISTORY                                                       */
649 /*                                                                        */
650 /*    DATE              NAME                      DESCRIPTION             */
651 /*                                                                        */
652 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
653 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
654 /*                                            resulting in version 6.1    */
655 /*  12-31-2020     Yuxin Zhou               Modified comment(s), improved */
656 /*                                            string length verification, */
657 /*                                            resulting in version 6.1.3  */
658 /*                                                                        */
659 /**************************************************************************/
_nx_pppoe_client_service_name_set_extended(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * service_name,UINT service_name_length)660 UINT  _nx_pppoe_client_service_name_set_extended(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *service_name, UINT service_name_length)
661 {
662 
663 UINT temp_service_name_length = 0;
664 
665     /* Get the length of service_name string.  */
666     if (_nx_utility_string_length_check((CHAR*)service_name, &temp_service_name_length, service_name_length))
667         return(NX_SIZE_ERROR);
668 
669     /* Check the service_name length.  */
670     if (service_name_length != temp_service_name_length)
671         return(NX_SIZE_ERROR);
672 
673     /* Obtain the IP internal mutex before processing the IP event.  */
674     tx_mutex_get(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
675 
676     /* Setup service name pointer.  */
677     pppoe_client_ptr -> nx_pppoe_service_name = service_name;
678 
679     /* Setup service name length.  */
680     pppoe_client_ptr -> nx_pppoe_service_name_length = service_name_length;
681 
682     /* Release the IP internal mutex.  */
683     tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
684 
685     /* Return success.  */
686     return(NX_PPPOE_CLIENT_SUCCESS);
687 }
688 
689 
690 /**************************************************************************/
691 /*                                                                        */
692 /*  FUNCTION                                               RELEASE        */
693 /*                                                                        */
694 /*    _nxe_pppoe_client_host_uniq_set                     PORTABLE C      */
695 /*                                                           6.1          */
696 /*  AUTHOR                                                                */
697 /*                                                                        */
698 /*    Yuxin Zhou, Microsoft Corporation                                   */
699 /*                                                                        */
700 /*  DESCRIPTION                                                           */
701 /*                                                                        */
702 /*    This function checks for errors in the PPPoE host uniq set          */
703 /*    function call.                                                      */
704 /*                                                                        */
705 /*  INPUT                                                                 */
706 /*                                                                        */
707 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
708 /*    host_uniq                             Pointer to an host unique.    */
709 /*                                            Host unique must be         */
710 /*                                            Null-terminated string.     */
711 /*                                                                        */
712 /*  OUTPUT                                                                */
713 /*                                                                        */
714 /*    status                                Completion status             */
715 /*                                                                        */
716 /*  CALLS                                                                 */
717 /*                                                                        */
718 /*    _nx_pppoe_client_host_uniq_set        Actual PPPoE host uniq set    */
719 /*                                            function                    */
720 /*                                                                        */
721 /*  CALLED BY                                                             */
722 /*                                                                        */
723 /*    Application                                                         */
724 /*                                                                        */
725 /*  RELEASE HISTORY                                                       */
726 /*                                                                        */
727 /*    DATE              NAME                      DESCRIPTION             */
728 /*                                                                        */
729 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
730 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
731 /*                                            resulting in version 6.1    */
732 /*                                                                        */
733 /**************************************************************************/
_nxe_pppoe_client_host_uniq_set(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * host_uniq)734 UINT  _nxe_pppoe_client_host_uniq_set(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *host_uniq)
735 {
736 
737 UINT    status;
738 
739     /* Check for invalid input pointers.  */
740     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
741         return(NX_PPPOE_CLIENT_PTR_ERROR);
742 
743     /* Call actual PPPoE host uniq set function.  */
744     status = _nx_pppoe_client_host_uniq_set(pppoe_client_ptr, host_uniq);
745 
746     /* Return completion status.  */
747     return(status);
748 }
749 
750 
751 /**************************************************************************/
752 /*                                                                        */
753 /*  FUNCTION                                               RELEASE        */
754 /*                                                                        */
755 /*    _nx_pppoe_client_host_uniq_set                      PORTABLE C      */
756 /*                                                           6.1          */
757 /*  AUTHOR                                                                */
758 /*                                                                        */
759 /*    Yuxin Zhou, Microsoft Corporation                                   */
760 /*                                                                        */
761 /*  DESCRIPTION                                                           */
762 /*                                                                        */
763 /*    This function sets the host unique for PPPoE Client.                */
764 /*                                                                        */
765 /*  INPUT                                                                 */
766 /*                                                                        */
767 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
768 /*    host_uniq                             Pointer to an host unique.    */
769 /*                                            Host unique must be         */
770 /*                                            Null-terminated string.     */
771 /*                                                                        */
772 /*  OUTPUT                                                                */
773 /*                                                                        */
774 /*    status                                Completion status             */
775 /*                                                                        */
776 /*  CALLS                                                                 */
777 /*                                                                        */
778 /*    _nx_utility_string_length_check       Check string length           */
779 /*    _nx_pppoe_client_host_uniq_set_extended                             */
780 /*                                          Actual PPPoE host uniq set    */
781 /*                                          function                      */
782 /*  CALLED BY                                                             */
783 /*                                                                        */
784 /*    Application                                                         */
785 /*                                                                        */
786 /*  RELEASE HISTORY                                                       */
787 /*                                                                        */
788 /*    DATE              NAME                      DESCRIPTION             */
789 /*                                                                        */
790 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
791 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
792 /*                                            resulting in version 6.1    */
793 /*                                                                        */
794 /**************************************************************************/
_nx_pppoe_client_host_uniq_set(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * host_uniq)795 UINT  _nx_pppoe_client_host_uniq_set(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *host_uniq)
796 {
797 UINT status;
798 UINT host_uniq_length = 0;
799 
800     /* Calculate the host_uniq length.  */
801     if (_nx_utility_string_length_check((CHAR *)host_uniq, &host_uniq_length, NX_MAX_STRING_LENGTH))
802     {
803         return(NX_SIZE_ERROR);
804     }
805 
806     status = _nx_pppoe_client_host_uniq_set_extended(pppoe_client_ptr, host_uniq, host_uniq_length);
807 
808     /* Return status.  */
809     return(status);
810 }
811 
812 
813 /**************************************************************************/
814 /*                                                                        */
815 /*  FUNCTION                                               RELEASE        */
816 /*                                                                        */
817 /*    _nxe_pppoe_client_host_uniq_set_extended            PORTABLE C      */
818 /*                                                           6.1          */
819 /*  AUTHOR                                                                */
820 /*                                                                        */
821 /*    Yuxin Zhou, Microsoft Corporation                                   */
822 /*                                                                        */
823 /*  DESCRIPTION                                                           */
824 /*                                                                        */
825 /*    This function checks for errors in the PPPoE host uniq set          */
826 /*    function call.                                                      */
827 /*                                                                        */
828 /*  INPUT                                                                 */
829 /*                                                                        */
830 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
831 /*    host_uniq                             Pointer to an host unique.    */
832 /*                                            Host unique must be         */
833 /*                                            Null-terminated string.     */
834 /*    host_uniq_length                      Length of host_uniq           */
835 /*                                                                        */
836 /*  OUTPUT                                                                */
837 /*                                                                        */
838 /*    status                                Completion status             */
839 /*                                                                        */
840 /*  CALLS                                                                 */
841 /*                                                                        */
842 /*    _nx_pppoe_client_host_uniq_set_extended                             */
843 /*                                          Actual PPPoE host uniq set    */
844 /*                                          function                      */
845 /*  CALLED BY                                                             */
846 /*                                                                        */
847 /*    Application                                                         */
848 /*                                                                        */
849 /*  RELEASE HISTORY                                                       */
850 /*                                                                        */
851 /*    DATE              NAME                      DESCRIPTION             */
852 /*                                                                        */
853 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
854 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
855 /*                                            resulting in version 6.1    */
856 /*                                                                        */
857 /**************************************************************************/
_nxe_pppoe_client_host_uniq_set_extended(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * host_uniq,UINT host_uniq_length)858 UINT  _nxe_pppoe_client_host_uniq_set_extended(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *host_uniq, UINT host_uniq_length)
859 {
860 
861 UINT    status;
862 
863     /* Check for invalid input pointers.  */
864     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
865         return(NX_PPPOE_CLIENT_PTR_ERROR);
866 
867     /* Call actual PPPoE host uniq set function.  */
868     status = _nx_pppoe_client_host_uniq_set_extended(pppoe_client_ptr, host_uniq, host_uniq_length);
869 
870     /* Return completion status.  */
871     return(status);
872 }
873 
874 
875 /**************************************************************************/
876 /*                                                                        */
877 /*  FUNCTION                                               RELEASE        */
878 /*                                                                        */
879 /*    _nx_pppoe_client_host_uniq_set_extended             PORTABLE C      */
880 /*                                                           6.1.3        */
881 /*  AUTHOR                                                                */
882 /*                                                                        */
883 /*    Yuxin Zhou, Microsoft Corporation                                   */
884 /*                                                                        */
885 /*  DESCRIPTION                                                           */
886 /*                                                                        */
887 /*    This function sets the host unique for PPPoE Client.                */
888 /*                                                                        */
889 /*    Note: The string of host_uniq must be NULL-terminated and length    */
890 /*    of host_uniq matches the length specified in the argument list.     */
891 /*                                                                        */
892 /*  INPUT                                                                 */
893 /*                                                                        */
894 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
895 /*    host_uniq                             Pointer to an host unique.    */
896 /*                                            Host unique must be         */
897 /*                                            Null-terminated string.     */
898 /*    host_uniq_length                      Length of host_uniq           */
899 /*                                                                        */
900 /*  OUTPUT                                                                */
901 /*                                                                        */
902 /*    status                                Completion status             */
903 /*                                                                        */
904 /*  CALLS                                                                 */
905 /*                                                                        */
906 /*    _nx_utility_string_length_check       Check string length           */
907 /*    tx_mutex_get                          Obtain a protection mutex     */
908 /*    tx_mutex_put                          Release protection mutex      */
909 /*                                                                        */
910 /*  CALLED BY                                                             */
911 /*                                                                        */
912 /*    Application                                                         */
913 /*                                                                        */
914 /*  RELEASE HISTORY                                                       */
915 /*                                                                        */
916 /*    DATE              NAME                      DESCRIPTION             */
917 /*                                                                        */
918 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
919 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
920 /*                                            resulting in version 6.1    */
921 /*  12-31-2020     Yuxin Zhou               Modified comment(s), improved */
922 /*                                            string length verification, */
923 /*                                            resulting in version 6.1.3  */
924 /*                                                                        */
925 /**************************************************************************/
_nx_pppoe_client_host_uniq_set_extended(NX_PPPOE_CLIENT * pppoe_client_ptr,UCHAR * host_uniq,UINT host_uniq_length)926 UINT  _nx_pppoe_client_host_uniq_set_extended(NX_PPPOE_CLIENT *pppoe_client_ptr, UCHAR *host_uniq, UINT host_uniq_length)
927 {
928 UINT temp_host_uniq_length = 0;
929 
930     /* Get the length of host_uniq string.  */
931     if (_nx_utility_string_length_check((CHAR*)host_uniq, &temp_host_uniq_length, host_uniq_length))
932         return(NX_SIZE_ERROR);
933 
934     /* Check the host_uniq length.  */
935     if (host_uniq_length != temp_host_uniq_length)
936         return(NX_SIZE_ERROR);
937 
938     /* Obtain the IP internal mutex before processing the IP event.  */
939     tx_mutex_get(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
940 
941     /* Setup host unique pointer.  */
942     pppoe_client_ptr -> nx_pppoe_host_uniq = host_uniq;
943 
944     /* Setup host unique length.  */
945     pppoe_client_ptr -> nx_pppoe_host_uniq_length = host_uniq_length;
946 
947     /* Release the IP internal mutex.  */
948     tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
949 
950     /* Return success.  */
951     return(NX_PPPOE_CLIENT_SUCCESS);
952 }
953 
954 
955 /**************************************************************************/
956 /*                                                                        */
957 /*  FUNCTION                                               RELEASE        */
958 /*                                                                        */
959 /*    _nxe_pppoe_client_session_connect                   PORTABLE C      */
960 /*                                                           6.1          */
961 /*  AUTHOR                                                                */
962 /*                                                                        */
963 /*    Yuxin Zhou, Microsoft Corporation                                   */
964 /*                                                                        */
965 /*  DESCRIPTION                                                           */
966 /*                                                                        */
967 /*    This function checks for errors in the PPPoE Client session connect */
968 /*    function call.                                                      */
969 /*                                                                        */
970 /*  INPUT                                                                 */
971 /*                                                                        */
972 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
973 /*    wait_option                           Suspension option             */
974 /*                                                                        */
975 /*  OUTPUT                                                                */
976 /*                                                                        */
977 /*    status                                Completion status             */
978 /*                                                                        */
979 /*  CALLS                                                                 */
980 /*                                                                        */
981 /*    _nx_pppoe_client_session_connect      Actual PPPoE connect function */
982 /*                                                                        */
983 /*  CALLED BY                                                             */
984 /*                                                                        */
985 /*    Application                                                         */
986 /*                                                                        */
987 /*  RELEASE HISTORY                                                       */
988 /*                                                                        */
989 /*    DATE              NAME                      DESCRIPTION             */
990 /*                                                                        */
991 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
992 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
993 /*                                            resulting in version 6.1    */
994 /*                                                                        */
995 /**************************************************************************/
_nxe_pppoe_client_session_connect(NX_PPPOE_CLIENT * pppoe_client_ptr,ULONG wait_option)996 UINT  _nxe_pppoe_client_session_connect(NX_PPPOE_CLIENT *pppoe_client_ptr, ULONG wait_option)
997 {
998 
999 UINT    status;
1000 
1001     /* Check for invalid input pointers.  */
1002     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
1003         return(NX_PPPOE_CLIENT_PTR_ERROR);
1004 
1005     /* Call actual PPPoE client instance enable function.  */
1006     status =  _nx_pppoe_client_session_connect(pppoe_client_ptr, wait_option);
1007 
1008     /* Return completion status.  */
1009     return(status);
1010 }
1011 
1012 
1013 /**************************************************************************/
1014 /*                                                                        */
1015 /*  FUNCTION                                               RELEASE        */
1016 /*                                                                        */
1017 /*    _nx_pppoe_client_session_connect                    PORTABLE C      */
1018 /*                                                           6.1          */
1019 /*  AUTHOR                                                                */
1020 /*                                                                        */
1021 /*    Yuxin Zhou, Microsoft Corporation                                   */
1022 /*                                                                        */
1023 /*  DESCRIPTION                                                           */
1024 /*                                                                        */
1025 /*    This function connects the PPPoE session.                           */
1026 /*                                                                        */
1027 /*  INPUT                                                                 */
1028 /*                                                                        */
1029 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
1030 /*    wait_option                           Suspension option             */
1031 /*                                                                        */
1032 /*  OUTPUT                                                                */
1033 /*                                                                        */
1034 /*    status                                Completion status             */
1035 /*                                                                        */
1036 /*  CALLS                                                                 */
1037 /*                                                                        */
1038 /*    _nx_pppoe_client_session_connect      Actual PPPoE connect function */
1039 /*                                                                        */
1040 /*  CALLED BY                                                             */
1041 /*                                                                        */
1042 /*    Application                                                         */
1043 /*                                                                        */
1044 /*  RELEASE HISTORY                                                       */
1045 /*                                                                        */
1046 /*    DATE              NAME                      DESCRIPTION             */
1047 /*                                                                        */
1048 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1049 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1050 /*                                            resulting in version 6.1    */
1051 /*                                                                        */
1052 /**************************************************************************/
_nx_pppoe_client_session_connect(NX_PPPOE_CLIENT * pppoe_client_ptr,ULONG wait_option)1053 UINT  _nx_pppoe_client_session_connect(NX_PPPOE_CLIENT *pppoe_client_ptr, ULONG wait_option)
1054 {
1055 
1056     /* Obtain the IP internal mutex before processing the IP event.  */
1057     tx_mutex_get(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1058 
1059     /* Check to PPPoE state.  */
1060     if (pppoe_client_ptr -> nx_pppoe_state != NX_PPPOE_CLIENT_STATE_INITIAL)
1061     {
1062 
1063         /* Release the IP internal mutex.  */
1064         tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1065 
1066         return(NX_PPPOE_CLIENT_INVALID_SESSION);
1067     }
1068 
1069     /* Activate the PPPoE client timer.  */
1070     tx_timer_activate(&pppoe_client_ptr -> nx_pppoe_timer);
1071 
1072     /* Update the state.  */
1073     pppoe_client_ptr -> nx_pppoe_state = NX_PPPOE_CLIENT_STATE_PADI_SENT;
1074 
1075     /* Set the retransmit timeout and count for PADI.  */
1076     pppoe_client_ptr -> nx_pppoe_rtr_timeout = NX_PPPOE_CLIENT_PADI_INIT_TIMEOUT;
1077     pppoe_client_ptr -> nx_pppoe_rtr_count = NX_PPPOE_CLIENT_PADI_COUNT - 1;
1078 
1079     /* Start to establish the PPPoE session connection.  */
1080     _nx_pppoe_client_discovery_send(pppoe_client_ptr, NX_PPPOE_CLIENT_CODE_PADI);
1081 
1082     /* Optionally suspend the thread.  If timeout occurs, return a connection timeout status.  If
1083        immediate response is selected, return a connection in progress status.  Only on a real
1084        connection should success be returned.  */
1085     if ((wait_option) && (_tx_thread_current_ptr != &(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_thread)))
1086     {
1087 
1088         /* Suspend the thread on this socket's connection attempt.  */
1089         /* Note: the IP protection mutex is released inside _nx_pppoe_client_session_thread_suspend().  */
1090 
1091         _nx_pppoe_client_session_thread_suspend(&(pppoe_client_ptr -> nx_pppoe_session_connect_suspended_thread), _nx_pppoe_client_session_connect_cleanup,
1092                                                 pppoe_client_ptr, &(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), wait_option);
1093 
1094         /* Just return the completion code.  */
1095         return(_tx_thread_current_ptr -> tx_thread_suspend_status);
1096     }
1097     else
1098     {
1099 
1100         /* No suspension is request, just release protection and return to the caller.  */
1101 
1102         /* Release the IP protection.  */
1103         tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1104 
1105         /* Return in-progress completion status.  */
1106         return(NX_IN_PROGRESS);
1107     }
1108 }
1109 
1110 
1111 /**************************************************************************/
1112 /*                                                                        */
1113 /*  FUNCTION                                               RELEASE        */
1114 /*                                                                        */
1115 /*    _nxe_pppoe_client_session_packet_send               PORTABLE C      */
1116 /*                                                           6.1          */
1117 /*  AUTHOR                                                                */
1118 /*                                                                        */
1119 /*    Yuxin Zhou, Microsoft Corporation                                   */
1120 /*                                                                        */
1121 /*  DESCRIPTION                                                           */
1122 /*                                                                        */
1123 /*    This function checks for errors in the PPPoE session packet send    */
1124 /*    function call.                                                      */
1125 /*                                                                        */
1126 /*  INPUT                                                                 */
1127 /*                                                                        */
1128 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
1129 /*    session_index                         Session index                 */
1130 /*    packet_ptr                            Pointer to packet to send     */
1131 /*                                                                        */
1132 /*  OUTPUT                                                                */
1133 /*                                                                        */
1134 /*    status                                Completion status             */
1135 /*                                                                        */
1136 /*  CALLS                                                                 */
1137 /*                                                                        */
1138 /*    _nx_pppoe_client_session_packet_send  Actual PPPoE Session data send*/
1139 /*                                            function                    */
1140 /*                                                                        */
1141 /*  CALLED BY                                                             */
1142 /*                                                                        */
1143 /*    Application                                                         */
1144 /*                                                                        */
1145 /*  RELEASE HISTORY                                                       */
1146 /*                                                                        */
1147 /*    DATE              NAME                      DESCRIPTION             */
1148 /*                                                                        */
1149 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1150 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1151 /*                                            resulting in version 6.1    */
1152 /*                                                                        */
1153 /**************************************************************************/
_nxe_pppoe_client_session_packet_send(NX_PPPOE_CLIENT * pppoe_client_ptr,NX_PACKET * packet_ptr)1154 UINT  _nxe_pppoe_client_session_packet_send(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr)
1155 {
1156 
1157 UINT    status;
1158 
1159     /* Check for invalid packet.  */
1160     if (packet_ptr == NX_NULL)
1161     {
1162         return(NX_PPPOE_CLIENT_PTR_ERROR);
1163     }
1164 
1165     /* Check for minimum packet length (PPP DATA Header).  */
1166     if (packet_ptr -> nx_packet_length < 2)
1167     {
1168 
1169         /* Release the packet.  */
1170         nx_packet_transmit_release(packet_ptr);
1171 
1172         return(NX_PPPOE_CLIENT_PACKET_PAYLOAD_ERROR);
1173     }
1174 
1175     /* Check for invalid input pointers.  */
1176     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
1177     {
1178 
1179         /* Adjust the packet prepend to remove the PPP header.  */
1180         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
1181         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
1182 
1183         /* Release the packet.  */
1184         nx_packet_transmit_release(packet_ptr);
1185 
1186         return(NX_PPPOE_CLIENT_PTR_ERROR);
1187     }
1188 
1189     /* Call actual PPPoE session packet_send function.  */
1190     status =  _nx_pppoe_client_session_packet_send(pppoe_client_ptr, packet_ptr);
1191 
1192     /* Return completion status.  */
1193     return(status);
1194 }
1195 
1196 
1197 /**************************************************************************/
1198 /*                                                                        */
1199 /*  FUNCTION                                               RELEASE        */
1200 /*                                                                        */
1201 /*    _nx_pppoe_client_session_packet_send                PORTABLE C      */
1202 /*                                                           6.1          */
1203 /*  AUTHOR                                                                */
1204 /*                                                                        */
1205 /*    Yuxin Zhou, Microsoft Corporation                                   */
1206 /*                                                                        */
1207 /*  DESCRIPTION                                                           */
1208 /*                                                                        */
1209 /*    This function builds an PPPoE Session packet and calls the          */
1210 /*    associated driver to send it out on the network.                    */
1211 /*                                                                        */
1212 /*  INPUT                                                                 */
1213 /*                                                                        */
1214 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
1215 /*    session_index                         Session index                 */
1216 /*    data_ptr                              Session Data pointer          */
1217 /*    data_length                           Length of Session Data        */
1218 /*                                                                        */
1219 /*  OUTPUT                                                                */
1220 /*                                                                        */
1221 /*    status                                Completion status             */
1222 /*                                                                        */
1223 /*  CALLS                                                                 */
1224 /*                                                                        */
1225 /*    tx_mutex_get                          Obtain a protection mutex     */
1226 /*    tx_mutex_put                          Release protection mutex      */
1227 /*    nx_packet_release                     Release packet to packet pool */
1228 /*    nx_packet_data_append                 Copies the specified data     */
1229 /*    _nx_pppoe_client_data_add             Add PPPoE data                */
1230 /*    _nx_pppoe_client_packet_send          Send out PPPoE packet         */
1231 /*                                                                        */
1232 /*  CALLED BY                                                             */
1233 /*                                                                        */
1234 /*    Application                                                         */
1235 /*                                                                        */
1236 /*  RELEASE HISTORY                                                       */
1237 /*                                                                        */
1238 /*    DATE              NAME                      DESCRIPTION             */
1239 /*                                                                        */
1240 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1241 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1242 /*                                            resulting in version 6.1    */
1243 /*                                                                        */
1244 /**************************************************************************/
_nx_pppoe_client_session_packet_send(NX_PPPOE_CLIENT * pppoe_client_ptr,NX_PACKET * packet_ptr)1245 UINT  _nx_pppoe_client_session_packet_send(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr)
1246 {
1247 
1248 NX_PPPOE_SERVER_SESSION    *server_session_ptr;
1249 UCHAR                      *work_ptr;
1250 
1251 
1252     /* Obtain the IP internal mutex.  */
1253     tx_mutex_get(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1254 
1255     /* Check to see if PPPoE session is established.  */
1256     if (pppoe_client_ptr -> nx_pppoe_state != NX_PPPOE_CLIENT_STATE_ESTABLISHED)
1257     {
1258 
1259         /* Adjust the packet prepend to remove the PPP header.  */
1260         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
1261         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
1262 
1263         /* Release the packet.  */
1264         nx_packet_transmit_release(packet_ptr);
1265 
1266         /* Release the IP internal mutex.  */
1267         tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1268 
1269         return(NX_PPPOE_CLIENT_SESSION_NOT_ESTABLISHED);
1270     }
1271 
1272     /* Check for an invalid packet prepend pointer.  */
1273     if ((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) < NX_PPPOE_CLIENT_OFFSET_PAYLOAD)
1274     {
1275 
1276         /* Adjust the packet prepend to remove the PPP header.  */
1277         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
1278         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
1279 
1280         /* Release the packet.  */
1281         nx_packet_transmit_release(packet_ptr);
1282 
1283         /* Release the IP internal mutex.  */
1284         tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1285 
1286         /* Return error code.  */
1287         return(NX_PPPOE_CLIENT_PACKET_PAYLOAD_ERROR);
1288     }
1289 
1290     /* Set the server session pointer.  */
1291     server_session_ptr = &(pppoe_client_ptr -> nx_pppoe_server_session);
1292 
1293     /* Set the work pointer.  */
1294     packet_ptr -> nx_packet_prepend_ptr -= NX_PPPOE_CLIENT_OFFSET_PAYLOAD;
1295     work_ptr = packet_ptr -> nx_packet_prepend_ptr;
1296 
1297     /* Added the PPPoE header.  */
1298     /*
1299      *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1300      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1301      * |  VER | TYPE  |      CODE       |         SESSION_ID           |
1302      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1303      * |           LENGTH               |          payload
1304      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1305     */
1306 
1307     /* Add version and type.  */
1308     _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_VER_TYPE, 1, NX_PPPOE_CLIENT_VERSION_TYPE);
1309 
1310     /* Add code.  */
1311     _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_CODE, 1, NX_PPPOE_CLIENT_CODE_ZERO);
1312 
1313     /* Add session id.  */
1314     _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_SESSION_ID, 2, server_session_ptr -> nx_pppoe_session_id);
1315 
1316     /* Add length.  */
1317     _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_LENGTH, 2, packet_ptr -> nx_packet_length);
1318 
1319     /* Update the packet length.  */
1320     packet_ptr -> nx_packet_length += NX_PPPOE_CLIENT_OFFSET_PAYLOAD;
1321 
1322     /* Send PPPoE session packet.  */
1323     _nx_pppoe_client_packet_send(pppoe_client_ptr, packet_ptr, NX_LINK_PPPOE_SESSION_SEND);
1324 
1325     /* Release the IP internal mutex.  */
1326     tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1327 
1328     /* Return success.  */
1329     return(NX_PPPOE_CLIENT_SUCCESS);
1330 }
1331 
1332 
1333 /**************************************************************************/
1334 /*                                                                        */
1335 /*  FUNCTION                                               RELEASE        */
1336 /*                                                                        */
1337 /*    _nxe_pppoe_client_session_terminate                 PORTABLE C      */
1338 /*                                                           6.1          */
1339 /*  AUTHOR                                                                */
1340 /*                                                                        */
1341 /*    Yuxin Zhou, Microsoft Corporation                                   */
1342 /*                                                                        */
1343 /*  DESCRIPTION                                                           */
1344 /*                                                                        */
1345 /*    This function checks for errors in the PPPoE session terminate      */
1346 /*    function call.                                                      */
1347 /*                                                                        */
1348 /*  INPUT                                                                 */
1349 /*                                                                        */
1350 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
1351 /*    session_index                         Session index                 */
1352 /*                                                                        */
1353 /*  OUTPUT                                                                */
1354 /*                                                                        */
1355 /*    status                                Completion status             */
1356 /*                                                                        */
1357 /*  CALLS                                                                 */
1358 /*                                                                        */
1359 /*    _nx_pppoe_client_session_terminate    Actual PPPoE Session terminate*/
1360 /*                                            function                    */
1361 /*                                                                        */
1362 /*  CALLED BY                                                             */
1363 /*                                                                        */
1364 /*    Application                                                         */
1365 /*                                                                        */
1366 /*  RELEASE HISTORY                                                       */
1367 /*                                                                        */
1368 /*    DATE              NAME                      DESCRIPTION             */
1369 /*                                                                        */
1370 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1371 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1372 /*                                            resulting in version 6.1    */
1373 /*                                                                        */
1374 /**************************************************************************/
_nxe_pppoe_client_session_terminate(NX_PPPOE_CLIENT * pppoe_client_ptr)1375 UINT  _nxe_pppoe_client_session_terminate(NX_PPPOE_CLIENT *pppoe_client_ptr)
1376 {
1377 
1378 UINT    status;
1379 
1380     /* Check for invalid input pointers.  */
1381     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
1382         return(NX_PPPOE_CLIENT_PTR_ERROR);
1383 
1384     /* Call actual PPPoE session terminate function.  */
1385     status =  _nx_pppoe_client_session_terminate(pppoe_client_ptr);
1386 
1387     /* Return completion status.  */
1388     return(status);
1389 }
1390 
1391 
1392 /**************************************************************************/
1393 /*                                                                        */
1394 /*  FUNCTION                                               RELEASE        */
1395 /*                                                                        */
1396 /*    _nx_pppoe_client_session_terminate                  PORTABLE C      */
1397 /*                                                           6.1          */
1398 /*  AUTHOR                                                                */
1399 /*                                                                        */
1400 /*    Yuxin Zhou, Microsoft Corporation                                   */
1401 /*                                                                        */
1402 /*  DESCRIPTION                                                           */
1403 /*                                                                        */
1404 /*    This function builds an PPPoE packet to terminate the session.      */
1405 /*                                                                        */
1406 /*  INPUT                                                                 */
1407 /*                                                                        */
1408 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
1409 /*    session_index                         Session index                 */
1410 /*                                                                        */
1411 /*  OUTPUT                                                                */
1412 /*                                                                        */
1413 /*    status                                Completion status             */
1414 /*                                                                        */
1415 /*  CALLS                                                                 */
1416 /*                                                                        */
1417 /*    tx_mutex_get                          Obtain a protection mutex     */
1418 /*    tx_mutex_put                          Release protection mutex      */
1419 /*    _nx_pppoe_client_discovery_send       Send out PPPoE packet         */
1420 /*    _nx_pppoe_client_session_cleanup      Cleanup PPPoE session         */
1421 /*                                                                        */
1422 /*  CALLED BY                                                             */
1423 /*                                                                        */
1424 /*    Application                                                         */
1425 /*                                                                        */
1426 /*  RELEASE HISTORY                                                       */
1427 /*                                                                        */
1428 /*    DATE              NAME                      DESCRIPTION             */
1429 /*                                                                        */
1430 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1431 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1432 /*                                            resulting in version 6.1    */
1433 /*                                                                        */
1434 /**************************************************************************/
_nx_pppoe_client_session_terminate(NX_PPPOE_CLIENT * pppoe_client_ptr)1435 UINT  _nx_pppoe_client_session_terminate(NX_PPPOE_CLIENT *pppoe_client_ptr)
1436 {
1437 
1438 UINT        status;
1439 
1440     /* Obtain the IP internal mutex before processing the IP event.  */
1441     tx_mutex_get(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1442 
1443     /* Check to see if PPPoE is established.  */
1444     if (pppoe_client_ptr -> nx_pppoe_state != NX_PPPOE_CLIENT_STATE_ESTABLISHED)
1445     {
1446 
1447         /* Release the IP internal mutex.  */
1448         tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1449 
1450         return(NX_PPPOE_CLIENT_SESSION_NOT_ESTABLISHED);
1451     }
1452 
1453     /* Terminate the PPPoE session.  */
1454     status = _nx_pppoe_client_discovery_send(pppoe_client_ptr, NX_PPPOE_CLIENT_CODE_PADT);
1455 
1456     /* Check the status.  */
1457     if (status == NX_PPPOE_CLIENT_SUCCESS)
1458     {
1459 
1460         /* Cleanup the session.  */
1461         _nx_pppoe_client_session_cleanup(pppoe_client_ptr);
1462     }
1463 
1464     /* Release the IP internal mutex.  */
1465     tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1466 
1467     /* Return status.  */
1468     return(status);
1469 }
1470 
1471 
1472 /**************************************************************************/
1473 /*                                                                        */
1474 /*  FUNCTION                                               RELEASE        */
1475 /*                                                                        */
1476 /*    _nxe_pppoe_client_session_get                       PORTABLE C      */
1477 /*                                                           6.1          */
1478 /*  AUTHOR                                                                */
1479 /*                                                                        */
1480 /*    Yuxin Zhou, Microsoft Corporation                                   */
1481 /*                                                                        */
1482 /*  DESCRIPTION                                                           */
1483 /*                                                                        */
1484 /*    This function checks for errors in the PPPoE session get function   */
1485 /*    call.                                                               */
1486 /*                                                                        */
1487 /*  INPUT                                                                 */
1488 /*                                                                        */
1489 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
1490 /*    session_index                         The index of Client Session   */
1491 /*    server_mac_msw                        Server physical address MSW   */
1492 /*    server_mac_lsw                        Server physical address LSW   */
1493 /*    session_id                            Session ID                    */
1494 /*                                                                        */
1495 /*  OUTPUT                                                                */
1496 /*                                                                        */
1497 /*    status                                Completion status             */
1498 /*                                                                        */
1499 /*  CALLS                                                                 */
1500 /*                                                                        */
1501 /*    _nx_pppoe_client_session_get          Actual PPPoE Session get      */
1502 /*                                            function                    */
1503 /*                                                                        */
1504 /*  CALLED BY                                                             */
1505 /*                                                                        */
1506 /*    Application                                                         */
1507 /*                                                                        */
1508 /*  RELEASE HISTORY                                                       */
1509 /*                                                                        */
1510 /*    DATE              NAME                      DESCRIPTION             */
1511 /*                                                                        */
1512 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1513 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1514 /*                                            resulting in version 6.1    */
1515 /*                                                                        */
1516 /**************************************************************************/
_nxe_pppoe_client_session_get(NX_PPPOE_CLIENT * pppoe_client_ptr,ULONG * client_mac_msw,ULONG * client_mac_lsw,ULONG * session_id)1517 UINT  _nxe_pppoe_client_session_get(NX_PPPOE_CLIENT *pppoe_client_ptr, ULONG *client_mac_msw, ULONG *client_mac_lsw, ULONG *session_id)
1518 {
1519 
1520 UINT    status;
1521 
1522     /* Check for invalid input pointers.  */
1523     if ((pppoe_client_ptr == NX_NULL) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
1524         return(NX_PPPOE_CLIENT_PTR_ERROR);
1525 
1526     /* Call actual PPPoE session get function.  */
1527     status =  _nx_pppoe_client_session_get(pppoe_client_ptr, client_mac_msw, client_mac_lsw, session_id);
1528 
1529     /* Return completion status.  */
1530     return(status);
1531 }
1532 
1533 
1534 /**************************************************************************/
1535 /*                                                                        */
1536 /*  FUNCTION                                               RELEASE        */
1537 /*                                                                        */
1538 /*    _nx_pppoe_client_session_get                        PORTABLE C      */
1539 /*                                                           6.1          */
1540 /*  AUTHOR                                                                */
1541 /*                                                                        */
1542 /*    Yuxin Zhou, Microsoft Corporation                                   */
1543 /*                                                                        */
1544 /*  DESCRIPTION                                                           */
1545 /*                                                                        */
1546 /*    This function builds an PPPoE packet to get the session physical    */
1547 /*    address and session id.                                             */
1548 /*                                                                        */
1549 /*  INPUT                                                                 */
1550 /*                                                                        */
1551 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
1552 /*    session_index                         The index of Client Session   */
1553 /*    server_mac_msw                        Server physical address MSW   */
1554 /*    server_mac_lsw                        Server physical address LSW   */
1555 /*    session_id                            Session ID                    */
1556 /*                                                                        */
1557 /*  OUTPUT                                                                */
1558 /*                                                                        */
1559 /*    status                                Completion status             */
1560 /*                                                                        */
1561 /*  CALLS                                                                 */
1562 /*                                                                        */
1563 /*    tx_mutex_get                          Obtain a protection mutex     */
1564 /*    tx_mutex_put                          Release protection mutex      */
1565 /*                                                                        */
1566 /*  CALLED BY                                                             */
1567 /*                                                                        */
1568 /*    Application                                                         */
1569 /*                                                                        */
1570 /*  RELEASE HISTORY                                                       */
1571 /*                                                                        */
1572 /*    DATE              NAME                      DESCRIPTION             */
1573 /*                                                                        */
1574 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1575 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1576 /*                                            resulting in version 6.1    */
1577 /*                                                                        */
1578 /**************************************************************************/
_nx_pppoe_client_session_get(NX_PPPOE_CLIENT * pppoe_client_ptr,ULONG * server_mac_msw,ULONG * server_mac_lsw,ULONG * session_id)1579 UINT  _nx_pppoe_client_session_get(NX_PPPOE_CLIENT *pppoe_client_ptr, ULONG *server_mac_msw, ULONG *server_mac_lsw, ULONG *session_id)
1580 {
1581 
1582 
1583     /* Obtain the IP internal mutex before processing the IP event.  */
1584     tx_mutex_get(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1585 
1586     /* Check to see if PPPoE session is established.  */
1587     if (pppoe_client_ptr -> nx_pppoe_state != NX_PPPOE_CLIENT_STATE_ESTABLISHED)
1588     {
1589 
1590         /* Release the IP internal mutex.  */
1591         tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1592 
1593         return(NX_PPPOE_CLIENT_SESSION_NOT_ESTABLISHED);
1594     }
1595 
1596     /* Yes, get the Server physical address MSW.  */
1597     if (server_mac_msw)
1598         *server_mac_msw = pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_msw;
1599 
1600     /* Yes, get the Server physical address LSW.  */
1601     if (server_mac_lsw)
1602         *server_mac_lsw = pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_lsw;
1603 
1604     /* Yes, get the Session ID.  */
1605     if (session_id)
1606         *session_id = pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_session_id;
1607 
1608     /* Release the IP internal mutex.  */
1609     tx_mutex_put(&(pppoe_client_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1610 
1611     /* Return status.  */
1612     return(NX_PPPOE_CLIENT_SUCCESS);
1613 }
1614 
1615 
1616 /**************************************************************************/
1617 /*                                                                        */
1618 /*  FUNCTION                                               RELEASE        */
1619 /*                                                                        */
1620 /*    _nx_pppoe_client_packet_deferred_receive            PORTABLE C      */
1621 /*                                                           6.1          */
1622 /*  AUTHOR                                                                */
1623 /*                                                                        */
1624 /*    Yuxin Zhou, Microsoft Corporation                                   */
1625 /*                                                                        */
1626 /*  DESCRIPTION                                                           */
1627 /*                                                                        */
1628 /*    This function receives a packet from the link driver (usually the   */
1629 /*    link driver's input ISR) and places it in the deferred receive      */
1630 /*    packet queue.  This moves the minimal receive packet processing     */
1631 /*    from the ISR to the PPPoE helper thread.                            */
1632 /*                                                                        */
1633 /*  INPUT                                                                 */
1634 /*                                                                        */
1635 /*    packet_ptr                            Pointer to packet to receive  */
1636 /*                                                                        */
1637 /*  OUTPUT                                                                */
1638 /*                                                                        */
1639 /*    status                                Completion status             */
1640 /*                                                                        */
1641 /*  CALLS                                                                 */
1642 /*                                                                        */
1643 /*    tx_event_flags_set                    Set events for PPPoE thread   */
1644 /*                                                                        */
1645 /*  CALLED BY                                                             */
1646 /*                                                                        */
1647 /*    Application                                                         */
1648 /*                                                                        */
1649 /*  RELEASE HISTORY                                                       */
1650 /*                                                                        */
1651 /*    DATE              NAME                      DESCRIPTION             */
1652 /*                                                                        */
1653 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1654 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1655 /*                                            resulting in version 6.1    */
1656 /*                                                                        */
1657 /**************************************************************************/
_nx_pppoe_client_packet_deferred_receive(NX_PACKET * packet_ptr)1658 VOID  _nx_pppoe_client_packet_deferred_receive(NX_PACKET *packet_ptr)
1659 {
1660 
1661 TX_INTERRUPT_SAVE_AREA
1662 
1663 
1664     /* Check to see if PPPoE instance is created.  */
1665     if (_nx_pppoe_client_created_ptr == NX_NULL)
1666     {
1667 
1668         /* Release the packet.  */;
1669         nx_packet_release(packet_ptr);
1670 
1671         return;
1672     }
1673 
1674     /* Check to see if PPPoE is ready to receive packet.  */
1675     if (_nx_pppoe_client_created_ptr -> nx_pppoe_state == NX_PPPOE_CLIENT_STATE_INITIAL)
1676     {
1677 
1678         /* Release the packet.  */;
1679         nx_packet_release(packet_ptr);
1680 
1681         return;
1682     }
1683 
1684     /* Disable interrupts.  */
1685     TX_DISABLE
1686 
1687     /* Check to see if the deferred processing queue is empty.  */
1688     if (_nx_pppoe_client_created_ptr -> nx_pppoe_deferred_received_packet_head)
1689     {
1690 
1691         /* Not empty, just place the packet at the end of the queue.  */
1692         (_nx_pppoe_client_created_ptr -> nx_pppoe_deferred_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
1693         packet_ptr -> nx_packet_queue_next =  NX_NULL;
1694         _nx_pppoe_client_created_ptr -> nx_pppoe_deferred_received_packet_tail = packet_ptr;
1695 
1696         /* Restore interrupts.  */
1697         TX_RESTORE
1698     }
1699     else
1700     {
1701 
1702         /* Empty deferred receive processing queue.  Just setup the head pointers and
1703            set the event flags to ensure the PPPoE helper thread looks at the deferred processing
1704            queue.  */
1705         _nx_pppoe_client_created_ptr -> nx_pppoe_deferred_received_packet_head = packet_ptr;
1706         _nx_pppoe_client_created_ptr -> nx_pppoe_deferred_received_packet_tail = packet_ptr;
1707         packet_ptr -> nx_packet_queue_next = NX_NULL;
1708 
1709         /* Restore interrupts.  */
1710         TX_RESTORE
1711 
1712         /* Wakeup PPPoE helper thread to process the PPPoE deferred receive.  */
1713         tx_event_flags_set(&(_nx_pppoe_client_created_ptr -> nx_pppoe_events), NX_PPPOE_CLIENT_PACKET_RECEIVE_EVENT, TX_OR);
1714     }
1715 }
1716 
1717 
1718 /**************************************************************************/
1719 /*                                                                        */
1720 /*  FUNCTION                                               RELEASE        */
1721 /*                                                                        */
1722 /*    _nx_pppoe_client_thread_entry                       PORTABLE C      */
1723 /*                                                           6.1          */
1724 /*  AUTHOR                                                                */
1725 /*                                                                        */
1726 /*    Yuxin Zhou, Microsoft Corporation                                   */
1727 /*                                                                        */
1728 /*  DESCRIPTION                                                           */
1729 /*                                                                        */
1730 /*    This function is the entry point for each PPPoE's helper thread.    */
1731 /*    The PPPoE helper thread is responsible for processing PPPoE packet. */
1732 /*                                                                        */
1733 /*    Note that the priority of this function is determined by the PPPoE  */
1734 /*    create service.                                                     */
1735 /*                                                                        */
1736 /*  INPUT                                                                 */
1737 /*                                                                        */
1738 /*    pppoe_client_ptr_value                Pointer to PPPoE control block*/
1739 /*                                                                        */
1740 /*  OUTPUT                                                                */
1741 /*                                                                        */
1742 /*    status                                Completion status             */
1743 /*                                                                        */
1744 /*  CALLS                                                                 */
1745 /*                                                                        */
1746 /*    tx_event_flags_get                    Suspend on event flags that   */
1747 /*                                            are used to signal this     */
1748 /*                                            thread what to do           */
1749 /*    tx_mutex_get                          Obtain protection mutex       */
1750 /*    tx_mutex_put                          Release protection mutex      */
1751 /*    _nx_pppoe_client_packet_receive       PPPoE receive packet          */
1752 /*                                            processing                  */
1753 /*    nx_packet_release                     Release packet to packet pool */
1754 /*    (pppoe_link_driver)                   User supplied link driver     */
1755 /*                                                                        */
1756 /*  CALLED BY                                                             */
1757 /*                                                                        */
1758 /*    ThreadX Scheduler                                                   */
1759 /*                                                                        */
1760 /*  RELEASE HISTORY                                                       */
1761 /*                                                                        */
1762 /*    DATE              NAME                      DESCRIPTION             */
1763 /*                                                                        */
1764 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1765 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1766 /*                                            resulting in version 6.1    */
1767 /*                                                                        */
1768 /**************************************************************************/
_nx_pppoe_client_thread_entry(ULONG pppoe_client_ptr_value)1769 static VOID _nx_pppoe_client_thread_entry(ULONG pppoe_client_ptr_value)
1770 {
1771 
1772 
1773 TX_INTERRUPT_SAVE_AREA
1774 
1775 #ifdef NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE
1776 NX_IP_DRIVER        driver_request;
1777 #endif
1778 NX_PPPOE_CLIENT    *pppoe_client_ptr;
1779 NX_IP              *ip_ptr;
1780 NX_PACKET          *packet_ptr;
1781 ULONG               pppoe_events;
1782 ULONG               timeout = 0;
1783 
1784 
1785     /* Setup the PPPoE pointer.  */
1786     pppoe_client_ptr =  (NX_PPPOE_CLIENT *) pppoe_client_ptr_value;
1787 
1788     /* Setup the IP pointer.  */
1789     ip_ptr = pppoe_client_ptr -> nx_pppoe_ip_ptr;
1790 
1791     /* Obtain the IP internal mutex before calling the driver.  */
1792     tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1793 
1794 #ifdef NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE
1795 
1796     /* Initialize and enable the hardware for physical interface.  */
1797 
1798     /* Is this a valid interface with a link driver associated with it?  */
1799     if((pppoe_client_ptr -> nx_pppoe_interface_ptr -> nx_interface_valid) && (pppoe_client_ptr -> nx_pppoe_link_driver_entry))
1800     {
1801 
1802         /* Yes; attach the interface to the device. */
1803         driver_request.nx_ip_driver_ptr        = ip_ptr;
1804         driver_request.nx_ip_driver_command    = NX_LINK_INTERFACE_ATTACH;
1805         driver_request.nx_ip_driver_interface  = pppoe_client_ptr -> nx_pppoe_interface_ptr;
1806         (pppoe_client_ptr -> nx_pppoe_link_driver_entry) (&driver_request);
1807 
1808         /* Call the link driver to initialize the hardware. Among other
1809            responsibilities, the driver is required to provide the
1810            Maximum Transfer Unit (MTU) for the physical layer. The MTU
1811            should represent the actual physical layer transfer size
1812            less the physical layer headers and trailers.  */
1813         driver_request.nx_ip_driver_ptr     = ip_ptr;
1814         driver_request.nx_ip_driver_command = NX_LINK_INITIALIZE;
1815         (pppoe_client_ptr -> nx_pppoe_link_driver_entry) (&driver_request);
1816 
1817         /* Call the link driver again to enable the interface.  */
1818         driver_request.nx_ip_driver_ptr     = ip_ptr;
1819         driver_request.nx_ip_driver_command = NX_LINK_ENABLE;
1820         (pppoe_client_ptr -> nx_pppoe_link_driver_entry) (&driver_request);
1821 
1822         /* Indicate to the IP software that IP to physical mapping
1823            is not required.  */
1824         pppoe_client_ptr -> nx_pppoe_interface_ptr -> nx_interface_address_mapping_needed = NX_FALSE;
1825     }
1826 #endif
1827 
1828     /* Loop to continue processing incoming bytes.  */
1829     while(NX_FOREVER)
1830     {
1831 
1832         /* Release the IP internal mutex.  */
1833         tx_mutex_put(&(ip_ptr -> nx_ip_protection));
1834 
1835         /* Pickup IP event flags.  */
1836         tx_event_flags_get(&(pppoe_client_ptr -> nx_pppoe_events), NX_PPPOE_CLIENT_ALL_EVENTS, TX_OR_CLEAR, &pppoe_events, NX_WAIT_FOREVER);
1837 
1838         /* Obtain the IP internal mutex before processing the IP event.  */
1839         tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1840 
1841         /* Check for PPPoE packet receive event.  */
1842         if (pppoe_events & NX_PPPOE_CLIENT_PACKET_RECEIVE_EVENT)
1843         {
1844 
1845             /* Loop to process all deferred packet requests.  */
1846             while (pppoe_client_ptr -> nx_pppoe_deferred_received_packet_head)
1847             {
1848 
1849                 /* Remove the first packet and process it!  */
1850 
1851                 /* Disable interrupts.  */
1852                 TX_DISABLE
1853 
1854                 /* Pickup the first packet.  */
1855                 packet_ptr =  pppoe_client_ptr -> nx_pppoe_deferred_received_packet_head;
1856 
1857                 /* Move the head pointer to the next packet.  */
1858                 pppoe_client_ptr -> nx_pppoe_deferred_received_packet_head =  packet_ptr -> nx_packet_queue_next;
1859 
1860                 /* Check for end of deferred processing queue.  */
1861                 if (pppoe_client_ptr -> nx_pppoe_deferred_received_packet_head == NX_NULL)
1862                 {
1863 
1864                     /* Yes, the queue is empty.  Set the tail pointer to NULL.  */
1865                     pppoe_client_ptr -> nx_pppoe_deferred_received_packet_tail =  NX_NULL;
1866                 }
1867 
1868                 /* Restore interrupts.  */
1869                 TX_RESTORE
1870 
1871 #ifndef NX_DISABLE_PACKET_CHAIN
1872 
1873                 /* Discard the chained packets.  */
1874                 if (packet_ptr -> nx_packet_next)
1875                 {
1876                     nx_packet_release(packet_ptr);
1877                     continue;
1878                 }
1879 #endif
1880 
1881                 /* Check for valid packet length.  */
1882                 if (packet_ptr -> nx_packet_length < NX_PPPOE_CLIENT_OFFSET_PAYLOAD)
1883                 {
1884 
1885                     /* Release the packet.  */
1886                     nx_packet_release(packet_ptr);
1887                     return;
1888                 }
1889 
1890                 /* Check the packet interface.  */
1891                 if ((packet_ptr -> nx_packet_ip_interface != NX_NULL) &&
1892                     (packet_ptr -> nx_packet_ip_interface != pppoe_client_ptr -> nx_pppoe_interface_ptr))
1893                 {
1894                     nx_packet_release(packet_ptr);
1895                     continue;
1896                 }
1897 
1898                 /* Call the actual PPPoE Client packet receive function.  */
1899                 _nx_pppoe_client_packet_receive(pppoe_client_ptr, packet_ptr);
1900             }
1901         }
1902 
1903         /* Check for PPPoE periodic timer event.  */
1904         if (pppoe_events & NX_PPPOE_CLIENT_TIMER_PERIODIC_EVENT)
1905         {
1906 
1907             /* Check if max number of PADI/PADR messages have been sent. */
1908             if (pppoe_client_ptr -> nx_pppoe_rtr_timeout != 0)
1909             {
1910 
1911                 /* Check on count down timer for sending out next PADI/PADR message. */
1912                 pppoe_client_ptr -> nx_pppoe_rtr_timeout--;
1913 
1914                 /* Check the timer.  */
1915                 if(pppoe_client_ptr -> nx_pppoe_rtr_timeout == 0)
1916                 {
1917 
1918                     /* It has expired. Send out a PADI/PADR message. */
1919 
1920                     /* Check if max number of PADI/PADR messages have been sent. */
1921                     if (pppoe_client_ptr -> nx_pppoe_rtr_count)
1922                     {
1923 
1924                         /* Retransmit PADI/PADR message. */
1925 
1926                         /* When a host does not receive a PADO/PADS packet with in a specified amount of time,
1927                            it should resend it's PADI/PADR packet and double the waiting period. RFC2516, Section8, Page8.  */
1928 
1929                         /* Check PPPoE state.  */
1930                         if (pppoe_client_ptr -> nx_pppoe_state == NX_PPPOE_CLIENT_STATE_PADI_SENT)
1931                         {
1932 
1933                             /* Calculate timeout.  */
1934                             timeout = ((ULONG)NX_PPPOE_CLIENT_PADI_INIT_TIMEOUT) << (ULONG)(NX_PPPOE_CLIENT_PADI_COUNT - pppoe_client_ptr -> nx_pppoe_rtr_count);
1935 
1936                             /* Send PADI.  */
1937                             _nx_pppoe_client_discovery_send(pppoe_client_ptr, NX_PPPOE_CLIENT_CODE_PADI);
1938                         }
1939 
1940                         /* Check PPPoE state.  */
1941                         if (pppoe_client_ptr -> nx_pppoe_state == NX_PPPOE_CLIENT_STATE_PADR_SENT)
1942                         {
1943 
1944                             /* Calculate timeout.  */
1945                             timeout = ((ULONG)NX_PPPOE_CLIENT_PADR_INIT_TIMEOUT) << (ULONG)(NX_PPPOE_CLIENT_PADR_COUNT - pppoe_client_ptr -> nx_pppoe_rtr_count);
1946 
1947                             /* Send PADR.  */
1948                             _nx_pppoe_client_discovery_send(pppoe_client_ptr, NX_PPPOE_CLIENT_CODE_PADR);
1949                         }
1950 
1951                         /* Update the retransmit count.  */
1952                         pppoe_client_ptr -> nx_pppoe_rtr_count --;
1953 
1954                         /* Set the retransmit timeout.  */
1955                         pppoe_client_ptr -> nx_pppoe_rtr_timeout = timeout;
1956                     }
1957                     else
1958                     {
1959 
1960                         /* Reach the max number of PADI/PADR have been sent.  */
1961 
1962                         /* Deactivate the PPPoE client timer.  */
1963                         tx_timer_deactivate(&(pppoe_client_ptr -> nx_pppoe_timer));
1964 
1965                         /* Cleanup the PPPoE session.  */
1966                         _nx_pppoe_client_session_cleanup(pppoe_client_ptr);
1967 
1968                         /* Determine if we need to wake a thread suspended on the connection.  */
1969                         if (pppoe_client_ptr -> nx_pppoe_session_connect_suspended_thread)
1970                         {
1971 
1972                             /* Resume the suspended thread.  */
1973                             _nx_pppoe_client_session_thread_resume(&(pppoe_client_ptr -> nx_pppoe_session_connect_suspended_thread), NX_PPPOE_CLIENT_SESSION_NOT_ESTABLISHED);
1974                         }
1975                     }
1976                 }
1977             }
1978         }
1979 
1980         /* Check for PPPoE event.  */
1981         if (pppoe_events & NX_PPPOE_CLIENT_SESSION_CONNECT_CLEANUP_EVENT)
1982         {
1983 
1984             if (pppoe_client_ptr -> nx_pppoe_session_connect_suspended_thread)
1985             {
1986                 _nx_pppoe_client_session_connect_cleanup(pppoe_client_ptr -> nx_pppoe_session_connect_suspended_thread NX_CLEANUP_ARGUMENT);
1987             }
1988         }
1989     }
1990 }
1991 
1992 
1993 /**************************************************************************/
1994 /*                                                                        */
1995 /*  FUNCTION                                               RELEASE        */
1996 /*                                                                        */
1997 /*    _nx_pppoe_client_timer_entry                        PORTABLE C      */
1998 /*                                                           6.1          */
1999 /*  AUTHOR                                                                */
2000 /*                                                                        */
2001 /*    Yuxin Zhou, Microsoft Corporation                                   */
2002 /*                                                                        */
2003 /*  DESCRIPTION                                                           */
2004 /*                                                                        */
2005 /*    This function handles waking up the PPPoE Client helper thread on a */
2006 /*    periodic basis.                                                     */
2007 /*                                                                        */
2008 /*  INPUT                                                                 */
2009 /*                                                                        */
2010 /*    pppoe_client_address                  PPPoE address in a ULONG      */
2011 /*                                                                        */
2012 /*  OUTPUT                                                                */
2013 /*                                                                        */
2014 /*    None                                                                */
2015 /*                                                                        */
2016 /*  CALLS                                                                 */
2017 /*                                                                        */
2018 /*    None                                                                */
2019 /*                                                                        */
2020 /*  CALLED BY                                                             */
2021 /*                                                                        */
2022 /*                                                                        */
2023 /*  RELEASE HISTORY                                                       */
2024 /*                                                                        */
2025 /*    DATE              NAME                      DESCRIPTION             */
2026 /*                                                                        */
2027 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2028 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2029 /*                                            resulting in version 6.1    */
2030 /*                                                                        */
2031 /**************************************************************************/
_nx_pppoe_client_timer_entry(ULONG pppoe_client_address)2032 static VOID  _nx_pppoe_client_timer_entry(ULONG pppoe_client_address)
2033 {
2034 
2035 NX_PPPOE_CLIENT *pppoe_client_ptr;
2036 
2037 
2038     /* Convert input parameter to an PPPoE Client pointer.  */
2039     pppoe_client_ptr =  (NX_PPPOE_CLIENT *)pppoe_client_address;
2040 
2041     /* Wakeup this PPPoE Client's helper thread.  */
2042     tx_event_flags_set(&(pppoe_client_ptr -> nx_pppoe_events), NX_PPPOE_CLIENT_TIMER_PERIODIC_EVENT, TX_OR);
2043 }
2044 
2045 
2046 /**************************************************************************/
2047 /*                                                                        */
2048 /*  FUNCTION                                               RELEASE        */
2049 /*                                                                        */
2050 /*    _nx_pppoe_client_packet_receive                     PORTABLE C      */
2051 /*                                                           6.1          */
2052 /*  AUTHOR                                                                */
2053 /*                                                                        */
2054 /*    Yuxin Zhou, Microsoft Corporation                                   */
2055 /*                                                                        */
2056 /*  DESCRIPTION                                                           */
2057 /*                                                                        */
2058 /*    This function receives a PPPoE packet from the PPPoE deferred       */
2059 /*    processing queue.                                                   */
2060 /*                                                                        */
2061 /*  INPUT                                                                 */
2062 /*                                                                        */
2063 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
2064 /*    packet_ptr                            Pointer to packet to receive  */
2065 /*                                                                        */
2066 /*  OUTPUT                                                                */
2067 /*                                                                        */
2068 /*    status                                Completion status             */
2069 /*                                                                        */
2070 /*  CALLS                                                                 */
2071 /*                                                                        */
2072 /*    nx_packet_release                     Release packet to packet pool */
2073 /*    _nx_pppoe_client_data_get             Get the PPPoE data            */
2074 /*    _nx_pppoe_client_discovery_packet_process                           */
2075 /*                                          Process discovery packet      */
2076 /*    _nx_pppoe_client_session_packet_process                             */
2077 /*                                          Process session packet        */
2078 /*                                                                        */
2079 /*  CALLED BY                                                             */
2080 /*                                                                        */
2081 /*    _nx_pppoe_client_thread_entry                                       */
2082 /*                                                                        */
2083 /*  RELEASE HISTORY                                                       */
2084 /*                                                                        */
2085 /*    DATE              NAME                      DESCRIPTION             */
2086 /*                                                                        */
2087 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2088 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2089 /*                                            resulting in version 6.1    */
2090 /*                                                                        */
2091 /**************************************************************************/
_nx_pppoe_client_packet_receive(NX_PPPOE_CLIENT * pppoe_client_ptr,NX_PACKET * packet_ptr)2092 VOID  _nx_pppoe_client_packet_receive(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr)
2093 {
2094 
2095 UCHAR                      *ethernet_header_ptr;
2096 ULONG                       dest_mac_msw;
2097 ULONG                       dest_mac_lsw;
2098 ULONG                       src_mac_msw;
2099 ULONG                       src_mac_lsw;
2100 UINT                        ethernet_type;
2101 
2102 
2103     /* Set up UCHAR pointer to ethernet header to extract client hardware address
2104        which we will use as the client's unique identifier.  */
2105     ethernet_header_ptr = packet_ptr -> nx_packet_prepend_ptr - NX_PPPOE_CLIENT_ETHER_HEADER_SIZE;
2106 
2107     /* Pickup the MSW and LSW of the destination MAC address.  */
2108     dest_mac_msw = (((ULONG) ethernet_header_ptr[0]) << 8)  | ((ULONG) ethernet_header_ptr[1]);
2109     dest_mac_lsw = (((ULONG) ethernet_header_ptr[2]) << 24) | (((ULONG) ethernet_header_ptr[3]) << 16) |
2110                     (((ULONG) ethernet_header_ptr[4]) << 8)  | ((ULONG) ethernet_header_ptr[5]);
2111 
2112     /* Check the destination hardware (mac address) field is filled in. */
2113     if ((dest_mac_msw == 0) && (dest_mac_lsw == 0))
2114     {
2115 
2116         /* Release the packet.  */
2117         nx_packet_release(packet_ptr);
2118         return;
2119     }
2120 
2121     /* Check if it is a broadcast message.
2122        Only PADI packet with the destination address set to the broadcast address, and PADI only can be sent from PPPoE Client.   */
2123     if ((dest_mac_msw == 0xFFFF) && (dest_mac_lsw == 0xFFFFFFFF))
2124     {
2125 
2126         /* Release the packet.  */
2127         nx_packet_release(packet_ptr);
2128         return;
2129     }
2130 
2131     /* Pickup the MSW and LSW of the source MAC address.  */
2132     src_mac_msw = (((ULONG) ethernet_header_ptr[6]) << 8)  | ((ULONG) ethernet_header_ptr[7]);
2133     src_mac_lsw = (((ULONG) ethernet_header_ptr[8]) << 24) | (((ULONG) ethernet_header_ptr[9]) << 16) |
2134                    (((ULONG) ethernet_header_ptr[10]) << 8)  | ((ULONG) ethernet_header_ptr[11]);
2135 
2136     /* Check the source hardware (mac address) field is filled in. */
2137     if ((src_mac_msw == 0) && (src_mac_lsw == 0))
2138     {
2139 
2140         /* Release the packet.  */
2141         nx_packet_release(packet_ptr);
2142         return;
2143     }
2144 
2145     /* Get the ethernet type.  */
2146     ethernet_type = _nx_pppoe_client_data_get(ethernet_header_ptr + 12, 2);
2147 
2148     /* Process the packet according to packet type. */
2149     if(ethernet_type == NX_PPPOE_CLIENT_ETHER_TYPE_DISCOVERY)
2150     {
2151 
2152         /* Process the discovery packet.  */
2153         _nx_pppoe_client_discovery_packet_process(pppoe_client_ptr, packet_ptr, src_mac_msw, src_mac_lsw);
2154     }
2155     else if(ethernet_type == NX_PPPOE_CLIENT_ETHER_TYPE_SESSION)
2156     {
2157 
2158         /* Process the session packet.  */
2159         _nx_pppoe_client_session_packet_process(pppoe_client_ptr, packet_ptr, src_mac_msw, src_mac_lsw);
2160     }
2161     else
2162     {
2163 
2164         /* Relase the packet.  */
2165         nx_packet_release(packet_ptr);
2166     }
2167 
2168     return;
2169 }
2170 
2171 
2172 /**************************************************************************/
2173 /*                                                                        */
2174 /*  FUNCTION                                               RELEASE        */
2175 /*                                                                        */
2176 /*    _nx_pppoe_client_discovery_packet_process           PORTABLE C      */
2177 /*                                                           6.1.3        */
2178 /*  AUTHOR                                                                */
2179 /*                                                                        */
2180 /*    Yuxin Zhou, Microsoft Corporation                                   */
2181 /*                                                                        */
2182 /*  DESCRIPTION                                                           */
2183 /*                                                                        */
2184 /*    This function processes an incoming discovery packet.               */
2185 /*                                                                        */
2186 /*  INPUT                                                                 */
2187 /*                                                                        */
2188 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
2189 /*    packet_ptr                            Pointer to packet to receive  */
2190 /*    client_mac_msw                        Client physical address MSW   */
2191 /*    client_mac_lsw                        Client physical address LSW   */
2192 /*    is_broadcast                          Broadcast flag                */
2193 /*                                                                        */
2194 /*  OUTPUT                                                                */
2195 /*                                                                        */
2196 /*    status                                Completion status             */
2197 /*                                                                        */
2198 /*  CALLS                                                                 */
2199 /*                                                                        */
2200 /*    nx_packet_release                     Release packet to packet pool */
2201 /*    _nx_pppoe_client_data_get             Get the PPPoE data            */
2202 /*    _nx_pppoe_client_tag_process          Process PPPoE tags            */
2203 /*    _nx_pppoe_client_discovery_send       Send discovery packet         */
2204 /*    _nx_pppoe_client_session_find         Find the PPPoE session        */
2205 /*    _nx_pppoe_client_session_cleanup      Cleanup the PPPoE session     */
2206 /*                                                                        */
2207 /*  CALLED BY                                                             */
2208 /*                                                                        */
2209 /*    _nx_pppoe_client_packet_receive       Receive the PPPoE packet      */
2210 /*                                                                        */
2211 /*  RELEASE HISTORY                                                       */
2212 /*                                                                        */
2213 /*    DATE              NAME                      DESCRIPTION             */
2214 /*                                                                        */
2215 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2216 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
2217 /*                                            packet length verification, */
2218 /*                                            verified memcpy use cases,  */
2219 /*                                            resulting in version 6.1    */
2220 /*  12-31-2020     Yuxin Zhou               Modified comment(s), improved */
2221 /*                                            string length verification, */
2222 /*                                            resulting in version 6.1.3  */
2223 /*                                                                        */
2224 /**************************************************************************/
_nx_pppoe_client_discovery_packet_process(NX_PPPOE_CLIENT * pppoe_client_ptr,NX_PACKET * packet_ptr,ULONG server_mac_msw,ULONG server_mac_lsw)2225 VOID  _nx_pppoe_client_discovery_packet_process(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr, ULONG server_mac_msw, ULONG server_mac_lsw)
2226 {
2227 
2228 
2229 UCHAR                      *pppoe_header_ptr;
2230 UINT                        is_accepted = NX_FALSE;
2231 ULONG                       ver_type;
2232 ULONG                       code;
2233 ULONG                       session_id;
2234 ULONG                       length;
2235 UCHAR                      *tag_ptr;
2236 ULONG                       tag_type;
2237 ULONG                       tag_length;
2238 UINT                        tag_index = 0;
2239 UINT                        tag_ac_name_count = 0;
2240 UINT                        tag_service_name_count = 0;
2241 UINT                        tag_service_name_valid = NX_FALSE;
2242 UINT                        tag_host_uniq_count = 0;
2243 UINT                        tag_host_uniq_valid = NX_FALSE;
2244 
2245 
2246     /* Setup the PPPoE header.  */
2247     pppoe_header_ptr = packet_ptr -> nx_packet_prepend_ptr;
2248 
2249     /* Pickup the version and type.  */
2250     ver_type = _nx_pppoe_client_data_get(pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_VER_TYPE, 1);
2251 
2252     /* Check the version and type.  */
2253     if (ver_type != NX_PPPOE_CLIENT_VERSION_TYPE)
2254     {
2255 
2256         /* Release the packet.  */
2257         nx_packet_release(packet_ptr);
2258         return;
2259     }
2260 
2261     /* Pickup the code.  */
2262     code = _nx_pppoe_client_data_get(pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_CODE, 1);
2263 
2264     /* Check the session state and the code of incoming packet.  */
2265     if (((pppoe_client_ptr -> nx_pppoe_state == NX_PPPOE_CLIENT_STATE_PADI_SENT) && (code == NX_PPPOE_CLIENT_CODE_PADO)) ||
2266         ((pppoe_client_ptr -> nx_pppoe_state == NX_PPPOE_CLIENT_STATE_PADR_SENT) && (code == NX_PPPOE_CLIENT_CODE_PADS)) ||
2267         ((pppoe_client_ptr -> nx_pppoe_state == NX_PPPOE_CLIENT_STATE_ESTABLISHED) && (code == NX_PPPOE_CLIENT_CODE_PADT)))
2268     {
2269 
2270         /* Packet can be accepted.  */
2271         is_accepted = NX_TRUE;
2272     }
2273 
2274     /* Ignore the packet that is not accepted.   */
2275     if (is_accepted != NX_TRUE)
2276     {
2277 
2278         /* Release the packet.  */
2279         nx_packet_release(packet_ptr);
2280         return;
2281     }
2282 
2283     /* Pickup the session id.  */
2284     session_id = _nx_pppoe_client_data_get(pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_SESSION_ID, 2);
2285 
2286     /* Check the session id.
2287        Session ID must be zero for PADO,
2288        Session ID must be not zero for PADS and PADT.
2289        Session ID must be same value for PADT.  */
2290     if (((code == NX_PPPOE_CLIENT_CODE_PADO) && (session_id != 0)) ||
2291         ((code != NX_PPPOE_CLIENT_CODE_PADO) && (session_id == 0)) ||
2292         ((code == NX_PPPOE_CLIENT_CODE_PADT) && (session_id != pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_session_id)))
2293     {
2294 
2295         /* Release the packet.  */
2296         nx_packet_release(packet_ptr);
2297         return;
2298     }
2299 
2300     /* Check the MAC address for PADS and PADT before process tags.  */
2301     if (code != NX_PPPOE_CLIENT_CODE_PADO)
2302     {
2303 
2304         if ((pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_msw != server_mac_msw) ||
2305             (pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_lsw != server_mac_lsw))
2306         {
2307 
2308             /* Release the packet.  */
2309             nx_packet_release(packet_ptr);
2310             return;
2311         }
2312     }
2313 
2314     /* Initialize the value.  */
2315     pppoe_client_ptr -> nx_pppoe_ac_name_size = 0;
2316     pppoe_client_ptr -> nx_pppoe_ac_cookie_size = 0;
2317     pppoe_client_ptr -> nx_pppoe_relay_session_id_size = 0;
2318     pppoe_client_ptr -> nx_pppoe_error_flag = 0;
2319 
2320     /* Pickup the length of tags.  */
2321     length = _nx_pppoe_client_data_get(pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_LENGTH, 2);
2322 
2323     /* Check for valid payload.  */
2324     if (length + NX_PPPOE_CLIENT_OFFSET_PAYLOAD > packet_ptr -> nx_packet_length)
2325     {
2326 
2327         /* Release the packet.  */
2328         nx_packet_release(packet_ptr);
2329         return;
2330     }
2331 
2332     /* Set the tag pointer.  */
2333     tag_ptr = pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_PAYLOAD;
2334 
2335     /* Loop to process the tag.  */
2336     while (tag_index + 4 <= length)
2337     {
2338 
2339         /* Pickup the tag type.  */
2340         tag_type = _nx_pppoe_client_data_get(tag_ptr + tag_index, 2);
2341 
2342         /* Update the index.  */
2343         tag_index += 2;
2344 
2345         /* Pickup the tag length.  */
2346         tag_length = _nx_pppoe_client_data_get(tag_ptr + tag_index, 2);
2347 
2348         /* Update the index.  */
2349         tag_index += 2;
2350 
2351         /* Check for valid tag length.  */
2352         if ((tag_index + tag_length) > length)
2353         {
2354 
2355             /* Release the packet.  */
2356             nx_packet_release(packet_ptr);
2357             return;
2358         }
2359 
2360         /* Process the option type. */
2361         switch (tag_type)
2362         {
2363 
2364             case NX_PPPOE_CLIENT_TAG_TYPE_END_OF_LIST:
2365             {
2366 
2367                 /* End tag.  */
2368                 break;
2369             }
2370             case NX_PPPOE_CLIENT_TAG_TYPE_SERVICE_NAME:
2371             {
2372 
2373                 /* Update the Service-Name count.  */
2374                 tag_service_name_count ++;
2375 
2376                 /* Check the tag length.  */
2377                 if (tag_length == 0)
2378                 {
2379 
2380                     /* When the tag length is zero this tag is used to indicate that any service is acceptable.  */
2381                     tag_service_name_valid = NX_TRUE;
2382                 }
2383                 else
2384                 {
2385 
2386                     /* Compare the service name with PPPoE Service name that Client is requesting.  */
2387                     if ((pppoe_client_ptr -> nx_pppoe_service_name_length == tag_length) &&
2388                         (!memcmp(tag_ptr + tag_index, pppoe_client_ptr -> nx_pppoe_service_name, tag_length)))
2389                     {
2390 
2391                         /* Update the information.  */
2392                         tag_service_name_valid = NX_TRUE;
2393                     }
2394                 }
2395 
2396                 break;
2397             }
2398             case NX_PPPOE_CLIENT_TAG_TYPE_AC_NAME:
2399             {
2400 
2401                 /* Check the cache for AC-Name.  */
2402                 if (tag_length > NX_PPPOE_CLIENT_MAX_AC_NAME_SIZE)
2403                 {
2404 
2405                     /* Release the packet.  */
2406                     nx_packet_release(packet_ptr);
2407                     return;
2408                 }
2409 
2410                 /* Update the AC-Name count.  */
2411                 tag_ac_name_count ++;
2412 
2413                 /* Save the AC-Name.  */
2414                 memcpy(pppoe_client_ptr -> nx_pppoe_ac_name, tag_ptr + tag_index, tag_length); /* Use case of memcpy is verified. */
2415 
2416                 /* Set the AC-Name size.  */
2417                 pppoe_client_ptr -> nx_pppoe_ac_name_size = tag_length;
2418 
2419                 break;
2420             }
2421             case NX_PPPOE_CLIENT_TAG_TYPE_HOST_UNIQ:
2422             {
2423 
2424                 /* Update the Host-Uniq count.  */
2425                 tag_host_uniq_count ++;
2426 
2427                 /* Check the Host-Uniq.  */
2428                 if ((pppoe_client_ptr -> nx_pppoe_host_uniq_length == tag_length) &&
2429                     (!memcmp(tag_ptr + tag_index, pppoe_client_ptr -> nx_pppoe_host_uniq, tag_length)))
2430                 {
2431 
2432                     /* Update the information.  */
2433                     tag_host_uniq_valid = NX_TRUE;
2434                 }
2435 
2436                 break;
2437             }
2438             case NX_PPPOE_CLIENT_TAG_TYPE_AC_COOKIE:
2439             {
2440 
2441                 /* Check the cache for AC-Cookie.  */
2442                 if (tag_length > NX_PPPOE_CLIENT_MAX_AC_COOKIE_SIZE)
2443                 {
2444 
2445                     /* Release the packet.  */
2446                     nx_packet_release(packet_ptr);
2447                     return;
2448                 }
2449 
2450                 /* Save the AC-Cookie.  */
2451                 memcpy(pppoe_client_ptr -> nx_pppoe_ac_cookie, tag_ptr + tag_index, tag_length); /* Use case of memcpy is verified. */
2452 
2453                 /* Set the AC-Cookie size.  */
2454                 pppoe_client_ptr -> nx_pppoe_ac_cookie_size = tag_length;
2455                 break;
2456             }
2457             case NX_PPPOE_CLIENT_TAG_TYPE_RELAY_SESSION_ID:
2458             {
2459 
2460                 /* Check the cache for Relay-Session_Id.  */
2461                 if (tag_length > NX_PPPOE_CLIENT_MAX_RELAY_SESSION_ID_SIZE)
2462                 {
2463 
2464                     /* Release the packet.  */
2465                     nx_packet_release(packet_ptr);
2466                     return;
2467                 }
2468 
2469                 /* Save the Relay-Session_Id.  */
2470                 memcpy(pppoe_client_ptr -> nx_pppoe_relay_session_id, tag_ptr + tag_index, tag_length); /* Use case of memcpy is verified. */
2471 
2472                 /* Set the Relay-Session_Id size.  */
2473                 pppoe_client_ptr -> nx_pppoe_relay_session_id_size = tag_length;
2474                 break;
2475             }
2476             case NX_PPPOE_CLIENT_TAG_TYPE_SERVICE_NAME_ERROR:
2477             {
2478 
2479                 /* Set the service name error flag.  */
2480                 pppoe_client_ptr -> nx_pppoe_error_flag |= NX_PPPOE_CLIENT_ERROR_SERVICE_NAME;
2481 
2482                 break;
2483             }
2484             case NX_PPPOE_CLIENT_TAG_TYPE_AC_SYSTEM_ERROR:
2485             {
2486 
2487                 /* Set the AC system error flag.  */
2488                 pppoe_client_ptr -> nx_pppoe_error_flag |= NX_PPPOE_CLIENT_ERROR_AC_SYSTEM;
2489 
2490                 break;
2491             }
2492             case NX_PPPOE_CLIENT_TAG_TYPE_GENERIC_ERROR:
2493             {
2494 
2495                 /* Set the generic error flag.  */
2496                 pppoe_client_ptr -> nx_pppoe_error_flag |= NX_PPPOE_CLIENT_ERROR_GENERIC;
2497 
2498                 break;
2499             }
2500             default:
2501                 break;
2502         }
2503 
2504         /* Move to the next tag. */
2505         tag_index += tag_length;
2506     }
2507 
2508     /* Now we can release the packet. */
2509     nx_packet_release(packet_ptr);
2510 
2511     /* Check the code value.  */
2512     if (code == NX_PPPOE_CLIENT_CODE_PADO)
2513     {
2514 
2515         /* PADO packet MUST contain one AC-Name TAG containing the Access Concentrator's name,
2516            a Service-Name TAG indentical to the one in the PADI.  RFC2516, Section5.2, Page6.  */
2517 
2518         /* Check AC-Name.  */
2519         if (tag_ac_name_count != 1)
2520             return;
2521 
2522         /* The Host MAY include a Host-Uniq TAG in a PADI or
2523            PADR. If the Access Concentrator receives this TAG, it MUST
2524            include the TAG unmodified in the associated PADO or PADS
2525            response. RFC2516, Appendix A, Page10.  */
2526         if (pppoe_client_ptr -> nx_pppoe_host_uniq)
2527         {
2528 
2529             /* Check if include valid Host-Uniq.  */
2530             if ((tag_host_uniq_count != 1) || (tag_host_uniq_valid != NX_TRUE))
2531                 return;
2532         }
2533         else
2534         {
2535 
2536             /* Check if include the Host-Uniq.  */
2537             if (tag_host_uniq_count)
2538                 return;
2539         }
2540 
2541         /* Check Service-Name.  */
2542         if (tag_service_name_valid != NX_TRUE)
2543             return;
2544 
2545         /* Check for error.  */
2546         if (pppoe_client_ptr -> nx_pppoe_error_flag)
2547             return;
2548 
2549         /* Choose one PPPoE Server.
2550            Since the PADI was broadcast, the Host may receive more than one
2551            PADO.  The Host looks through the PADO packets it receives and
2552            chooses one.  The choice can be based on the AC-Name or the Services
2553            offered.  The Host then sends one PADR packet to the Access
2554            Concentrator that it has chosen. RFC2516, Section5.3, Page6.  */
2555 
2556         /* Simplify the logic, we choose the first PPPoE Server sent out PADO.  */
2557 
2558         /* Record server information.  */
2559         pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_msw = server_mac_msw;
2560         pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_lsw = server_mac_lsw;
2561 
2562         /* Send PPPoE Active Discovery Offer packet.  */
2563         _nx_pppoe_client_discovery_send(pppoe_client_ptr, NX_PPPOE_CLIENT_CODE_PADR);
2564 
2565         /* Update the state.  */
2566         pppoe_client_ptr -> nx_pppoe_state = NX_PPPOE_CLIENT_STATE_PADR_SENT;
2567 
2568         /* Set the retransmit timeout and count for PADR.  */
2569         pppoe_client_ptr -> nx_pppoe_rtr_timeout = NX_PPPOE_CLIENT_PADR_INIT_TIMEOUT;
2570         pppoe_client_ptr -> nx_pppoe_rtr_count = NX_PPPOE_CLIENT_PADR_COUNT - 1;
2571     }
2572     else if (code == NX_PPPOE_CLIENT_CODE_PADS)
2573     {
2574 
2575         /* The PADS packet contains exactly one TAG of TAG_TYPE Service-Name. RFC2516, Section5.4, Page6.  */
2576 
2577         /* Check Service-Name.  */
2578         if ((tag_service_name_count != 1) || (tag_service_name_valid != NX_TRUE))
2579             return;
2580 
2581         /* Check for error.  */
2582         if (pppoe_client_ptr -> nx_pppoe_error_flag)
2583             return;
2584 
2585         /* Record the session id.  */
2586         pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_session_id = (USHORT)session_id;
2587 
2588         /* Update the state.  */
2589         pppoe_client_ptr -> nx_pppoe_state = NX_PPPOE_CLIENT_STATE_ESTABLISHED;
2590 
2591         /* Deactivate the PPPoE client timer.  */
2592         tx_timer_deactivate(&(pppoe_client_ptr -> nx_pppoe_timer));
2593 
2594         /* Determine if we need to wake a thread suspended on the connection.  */
2595         if (pppoe_client_ptr -> nx_pppoe_session_connect_suspended_thread)
2596         {
2597 
2598             /* Resume the suspended thread.  */
2599             _nx_pppoe_client_session_thread_resume(&(pppoe_client_ptr -> nx_pppoe_session_connect_suspended_thread), NX_PPPOE_CLIENT_SUCCESS);
2600         }
2601     }
2602     else if (code == NX_PPPOE_CLIENT_CODE_PADT)
2603     {
2604 
2605         /* Cleanup the PPPoE session.  */
2606         _nx_pppoe_client_session_cleanup(pppoe_client_ptr);
2607     }
2608 }
2609 
2610 
2611 /**************************************************************************/
2612 /*                                                                        */
2613 /*  FUNCTION                                               RELEASE        */
2614 /*                                                                        */
2615 /*    _nx_pppoe_client_session_packet_process             PORTABLE C      */
2616 /*                                                           6.1          */
2617 /*  AUTHOR                                                                */
2618 /*                                                                        */
2619 /*    Yuxin Zhou, Microsoft Corporation                                   */
2620 /*                                                                        */
2621 /*  DESCRIPTION                                                           */
2622 /*                                                                        */
2623 /*    This function processes an incoming session packet.                 */
2624 /*                                                                        */
2625 /*  INPUT                                                                 */
2626 /*                                                                        */
2627 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
2628 /*    packet_ptr                            Pointer to packet to receive  */
2629 /*    client_mac_msw                        Client physical address MSW   */
2630 /*    client_mac_lsw                        Client physical address LSW   */
2631 /*                                                                        */
2632 /*  OUTPUT                                                                */
2633 /*                                                                        */
2634 /*    status                                Completion status             */
2635 /*                                                                        */
2636 /*  CALLS                                                                 */
2637 /*                                                                        */
2638 /*    nx_packet_release                     Release packet to packet pool */
2639 /*    _nx_pppoe_client_data_get             Get the PPPoE data            */
2640 /*    _nx_pppoe_client_session_find         Find the PPPoE session        */
2641 /*                                                                        */
2642 /*  CALLED BY                                                             */
2643 /*                                                                        */
2644 /*    _nx_pppoe_client_packet_receive       Receive the PPPoE packet      */
2645 /*                                                                        */
2646 /*  RELEASE HISTORY                                                       */
2647 /*                                                                        */
2648 /*    DATE              NAME                      DESCRIPTION             */
2649 /*                                                                        */
2650 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2651 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2652 /*                                            resulting in version 6.1    */
2653 /*                                                                        */
2654 /**************************************************************************/
_nx_pppoe_client_session_packet_process(NX_PPPOE_CLIENT * pppoe_client_ptr,NX_PACKET * packet_ptr,ULONG server_mac_msw,ULONG server_mac_lsw)2655 static VOID  _nx_pppoe_client_session_packet_process(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr, ULONG server_mac_msw, ULONG server_mac_lsw)
2656 {
2657 
2658 
2659 UCHAR                      *pppoe_header_ptr;
2660 ULONG                       ver_type;
2661 ULONG                       code;
2662 ULONG                       session_id;
2663 ULONG                       length;
2664 NX_PPPOE_SERVER_SESSION    *server_session_ptr;
2665 
2666 
2667     /* Setup the PPPoE header.  */
2668     pppoe_header_ptr = packet_ptr -> nx_packet_prepend_ptr;
2669 
2670     /* Pickup the version and type.  */
2671     ver_type = _nx_pppoe_client_data_get(pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_VER_TYPE, 1);
2672 
2673     /* Check the version and type.  */
2674     if (ver_type != NX_PPPOE_CLIENT_VERSION_TYPE)
2675     {
2676 
2677         /* Release the packet.  */
2678         nx_packet_release(packet_ptr);
2679         return;
2680     }
2681 
2682     /* Pickup the code.  */
2683     code = _nx_pppoe_client_data_get(pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_CODE, 1);
2684 
2685     /* Check the code.  */
2686     if (code != NX_PPPOE_CLIENT_CODE_ZERO)
2687     {
2688 
2689         /* Release the packet.  */
2690         nx_packet_release(packet_ptr);
2691         return;
2692     }
2693 
2694     /* Pickup the session id.  */
2695     session_id = _nx_pppoe_client_data_get(pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_SESSION_ID, 2);
2696 
2697     /* Check the session id.  */
2698     if (session_id == 0)
2699     {
2700 
2701         /* Release the packet.  */
2702         nx_packet_release(packet_ptr);
2703         return;
2704     }
2705 
2706     /* Check the session state.  */
2707     if (pppoe_client_ptr -> nx_pppoe_state != NX_PPPOE_CLIENT_STATE_ESTABLISHED)
2708     {
2709 
2710         /* Release the packet.  */
2711         nx_packet_release(packet_ptr);
2712         return;
2713     }
2714 
2715     /* Set the server session pointer.  */
2716     server_session_ptr = &(pppoe_client_ptr -> nx_pppoe_server_session);
2717 
2718     /* Check the session id and server MAC address.  */
2719     if ((session_id != server_session_ptr -> nx_pppoe_session_id) ||
2720         (server_mac_msw != server_session_ptr -> nx_pppoe_physical_address_msw) ||
2721         (server_mac_lsw != server_session_ptr -> nx_pppoe_physical_address_lsw))
2722     {
2723 
2724         /* Release the packet.  */
2725         nx_packet_release(packet_ptr);
2726         return;
2727     }
2728 
2729     /* Setup the prepend pointer to point the payload of PPPoE.  */
2730     packet_ptr -> nx_packet_prepend_ptr += NX_PPPOE_CLIENT_OFFSET_PAYLOAD;
2731     packet_ptr -> nx_packet_length -= NX_PPPOE_CLIENT_OFFSET_PAYLOAD;
2732 
2733     /* Pickup the length of payload.  */
2734     length = _nx_pppoe_client_data_get(pppoe_header_ptr + NX_PPPOE_CLIENT_OFFSET_LENGTH, 2);
2735 
2736     /* Check for valid payload.  */
2737     if (length > packet_ptr -> nx_packet_length)
2738     {
2739 
2740         /* Release the packet.  */
2741         nx_packet_release(packet_ptr);
2742         return;
2743     }
2744 
2745     /* Remove the Ethernet padding.  */
2746     if (length < packet_ptr -> nx_packet_length)
2747     {
2748         packet_ptr -> nx_packet_append_ptr -= (packet_ptr -> nx_packet_length - length);
2749         packet_ptr -> nx_packet_length -= (packet_ptr -> nx_packet_length - length);
2750     }
2751 
2752     /* Check the PPPoE receive function.  */
2753     if (pppoe_client_ptr -> nx_pppoe_packet_receive)
2754     {
2755 
2756         /* Call the function to receive the data frame.
2757            Notice: the receive function must release this packet.  */
2758         pppoe_client_ptr -> nx_pppoe_packet_receive(packet_ptr);
2759     }
2760     else
2761     {
2762 
2763         /* Release the packet.  */
2764         nx_packet_release(packet_ptr);
2765     }
2766 
2767     return;
2768 }
2769 
2770 
2771 /**************************************************************************/
2772 /*                                                                        */
2773 /*  FUNCTION                                               RELEASE        */
2774 /*                                                                        */
2775 /*    _nx_pppoe_client_discovery_send                     PORTABLE C      */
2776 /*                                                           6.1.3        */
2777 /*  AUTHOR                                                                */
2778 /*                                                                        */
2779 /*    Yuxin Zhou, Microsoft Corporation                                   */
2780 /*                                                                        */
2781 /*  DESCRIPTION                                                           */
2782 /*                                                                        */
2783 /*    This function sends a PPPoE discovery packet.                       */
2784 /*                                                                        */
2785 /*  INPUT                                                                 */
2786 /*                                                                        */
2787 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
2788 /*    client_session_ptr                    Pointer to Client Session     */
2789 /*    code                                  PPPoE code                    */
2790 /*                                                                        */
2791 /*  OUTPUT                                                                */
2792 /*                                                                        */
2793 /*    status                                Completion status             */
2794 /*                                                                        */
2795 /*  CALLS                                                                 */
2796 /*                                                                        */
2797 /*    nx_packet_allocate                    Allocate a packet for the     */
2798 /*                                            PPPoE Discovery             */
2799 /*    nx_packet_release                     Release packet to packet pool */
2800 /*    _nx_pppoe_client_data_add             Add PPPoE data                */
2801 /*    _nx_pppoe_client_tag_string_add       Add PPPoE tag                 */
2802 /*    _nx_pppoe_client_packet_send          Send out PPPoE packet         */
2803 /*    _nx_pppoe_client_session_find         Find the PPPoE session        */
2804 /*                                                                        */
2805 /*  CALLED BY                                                             */
2806 /*                                                                        */
2807 /*    _nx_pppoe_client_session_terminate    Terminate the PPPoE session   */
2808 /*    _nx_pppoe_client_discovery_packet_process                           */
2809 /*                                          Process PPPoE Discovery packet*/
2810 /*                                                                        */
2811 /*  RELEASE HISTORY                                                       */
2812 /*                                                                        */
2813 /*    DATE              NAME                      DESCRIPTION             */
2814 /*                                                                        */
2815 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2816 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2817 /*                                            resulting in version 6.1    */
2818 /*  12-31-2020     Yuxin Zhou               Modified comment(s), improved */
2819 /*                                            string length verification, */
2820 /*                                            resulting in version 6.1.3  */
2821 /*                                                                        */
2822 /**************************************************************************/
_nx_pppoe_client_discovery_send(NX_PPPOE_CLIENT * pppoe_client_ptr,UINT code)2823 static UINT    _nx_pppoe_client_discovery_send(NX_PPPOE_CLIENT *pppoe_client_ptr, UINT code)
2824 {
2825 
2826 
2827 NX_PACKET       *packet_ptr;
2828 UCHAR           *work_ptr;
2829 UINT            status;
2830 UINT            index = 0;
2831 
2832 
2833     /* Allocate a PPPoE packet.  */
2834     status =  nx_packet_allocate(pppoe_client_ptr -> nx_pppoe_packet_pool_ptr, &packet_ptr, NX_PHYSICAL_HEADER, NX_NO_WAIT);
2835 
2836     /* Was the packet allocation successful?  */
2837     if (status != NX_SUCCESS)
2838     {
2839 
2840         /* Return status.  */
2841         return(status);
2842     }
2843 
2844     /* Set the work pointer.  */
2845     work_ptr = packet_ptr -> nx_packet_prepend_ptr;
2846 
2847     /* First skip the PPPoE header.  */
2848     index += NX_PPPOE_CLIENT_OFFSET_PAYLOAD;
2849 
2850     /* The PPPoE payload contains zero or more TAGs.  A TAG is a TLV (type-length-value) construct and is defined as follows.  */
2851 
2852     /*                      1                   2                   3
2853      *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2854      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2855      * |          TAG_TYPE              |         TAG_LENGTH           |
2856      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2857      * |          TAG_VALUE  ...
2858      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2859     */
2860 
2861     /* Add the PPPoE tags.  */
2862     if (code == NX_PPPOE_CLIENT_CODE_PADI)
2863     {
2864 
2865         /* The PADI packet MUST contain exactly one TAG of TAG_TYPE Service-Name, indicating the service the host is requesting,
2866            and any number of other TAG types. RFC2516, Section5.1, Page5.  */
2867         if (pppoe_client_ptr -> nx_pppoe_service_name)
2868         {
2869 
2870             if (((ULONG)(packet_ptr -> nx_packet_data_end) - (ULONG)(&work_ptr[index])) >=
2871                 (4 + pppoe_client_ptr -> nx_pppoe_service_name_length))
2872             {
2873 
2874                 /* Added the Service-Name tag.  */
2875                 _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_SERVICE_NAME, pppoe_client_ptr -> nx_pppoe_service_name_length, pppoe_client_ptr -> nx_pppoe_service_name, &index);
2876             }
2877             else
2878             {
2879 
2880                 /* Packet too small. */
2881                 nx_packet_release(packet_ptr);
2882                 return(NX_PPPOE_CLIENT_PACKET_PAYLOAD_ERROR);
2883             }
2884         }
2885         else
2886         {
2887 
2888             /* Added the Service-Name tag.  */
2889             _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_SERVICE_NAME, 0, NX_NULL, &index);
2890         }
2891 
2892         /* The Host MAY include a Host-Uniq TAG in a PADI or PADR.  */
2893         if (pppoe_client_ptr -> nx_pppoe_host_uniq)
2894         {
2895 
2896             if (((ULONG)(packet_ptr -> nx_packet_data_end) - (ULONG)(&work_ptr[index])) >=
2897                 (4 + pppoe_client_ptr -> nx_pppoe_host_uniq_length))
2898             {
2899 
2900                 /* Added the Host-Uniq tag.  */
2901                 _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_HOST_UNIQ, pppoe_client_ptr -> nx_pppoe_host_uniq_length, pppoe_client_ptr -> nx_pppoe_host_uniq, &index);
2902             }
2903             else
2904             {
2905 
2906                 /* Packet too small. */
2907                 nx_packet_release(packet_ptr);
2908                 return(NX_PPPOE_CLIENT_PACKET_PAYLOAD_ERROR);
2909             }
2910         }
2911     }
2912     else if (code == NX_PPPOE_CLIENT_CODE_PADR)
2913     {
2914 
2915         /* The PADR packet MUST contain exactly one TAG of TAG_TYPE Service-Name, indicating the service the host is requesting,
2916            and any number of other TAG types. RFC2516, Section5.3, Page6.  */
2917         if (pppoe_client_ptr -> nx_pppoe_service_name)
2918         {
2919 
2920             if (((ULONG)(packet_ptr -> nx_packet_data_end) - (ULONG)(&work_ptr[index])) >=
2921                 (4 + pppoe_client_ptr -> nx_pppoe_service_name_length))
2922             {
2923 
2924                 /* Added the Service-Name tag.  */
2925                 _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_SERVICE_NAME, pppoe_client_ptr -> nx_pppoe_service_name_length, pppoe_client_ptr -> nx_pppoe_service_name, &index);
2926             }
2927             else
2928             {
2929 
2930                 /* Packet too small. */
2931                 nx_packet_release(packet_ptr);
2932                 return(NX_PPPOE_CLIENT_PACKET_PAYLOAD_ERROR);
2933             }
2934         }
2935         else
2936         {
2937 
2938             /* Added the Service-Name tag.  */
2939             _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_SERVICE_NAME, 0, NX_NULL, &index);
2940         }
2941 
2942         /* The Host MAY include a Host-Uniq TAG in a PADI or PADR.  */
2943         if (pppoe_client_ptr -> nx_pppoe_host_uniq)
2944         {
2945 
2946             if (((ULONG)(packet_ptr -> nx_packet_data_end) - (ULONG)(&work_ptr[index])) >=
2947                 (4 + pppoe_client_ptr -> nx_pppoe_host_uniq_length))
2948             {
2949 
2950                 /* Added the Host-Uniq tag.  */
2951                 _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_HOST_UNIQ, pppoe_client_ptr -> nx_pppoe_host_uniq_length, pppoe_client_ptr -> nx_pppoe_host_uniq, &index);
2952             }
2953             else
2954             {
2955 
2956                 /* Packet too small. */
2957                 nx_packet_release(packet_ptr);
2958                 return(NX_PPPOE_CLIENT_PACKET_PAYLOAD_ERROR);
2959             }
2960         }
2961 
2962         /* If a Host receives AC-Cookie tag, it MUST return the TAG unmodified in the following PADR.  */
2963         if (pppoe_client_ptr -> nx_pppoe_ac_cookie_size)
2964         {
2965 
2966             /* Added the AC-Cookie tag.  */
2967             _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_AC_COOKIE, pppoe_client_ptr -> nx_pppoe_ac_cookie_size, pppoe_client_ptr -> nx_pppoe_ac_cookie, &index);
2968         }
2969 
2970         /* If either the Host or Access Concentrator receives Relay-Session-Id TAG they MUST include it unmodified in any discovery packet they send as a response.  */
2971         if (pppoe_client_ptr -> nx_pppoe_relay_session_id_size)
2972         {
2973 
2974             /* Added the Host-Uniq tag.  */
2975             _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_HOST_UNIQ, pppoe_client_ptr -> nx_pppoe_relay_session_id_size, pppoe_client_ptr -> nx_pppoe_relay_session_id, &index);
2976         }
2977     }
2978     else if (code == NX_PPPOE_CLIENT_CODE_PADT)
2979     {
2980 
2981         /* If either the Host or Access Concentrator receives Relay-Session-Id TAG they MUST include it unmodified in any discovery packet they send as a response.  */
2982         if (pppoe_client_ptr -> nx_pppoe_relay_session_id_size)
2983         {
2984 
2985             /* Added the Host-Uniq tag.  */
2986             _nx_pppoe_client_tag_string_add(work_ptr, NX_PPPOE_CLIENT_TAG_TYPE_HOST_UNIQ, pppoe_client_ptr -> nx_pppoe_relay_session_id_size, pppoe_client_ptr -> nx_pppoe_relay_session_id, &index);
2987         }
2988     }
2989 
2990     /* Add the PPPoE header.  */
2991     /*
2992      *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2993      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2994      * |  VER | TYPE  |      CODE       |         SESSION_ID           |
2995      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2996      * |           LENGTH               |          payload
2997      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2998     */
2999 
3000     /* Add version and type.  */
3001     _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_VER_TYPE, 1, NX_PPPOE_CLIENT_VERSION_TYPE);
3002 
3003     /* Add code.  */
3004     _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_CODE, 1, code);
3005 
3006     /* Add the Session id.  */
3007     if (code == NX_PPPOE_CLIENT_CODE_PADT)
3008     {
3009 
3010         /* Add session id.  */
3011         _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_SESSION_ID, 2, pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_session_id);
3012     }
3013     else
3014     {
3015 
3016         /* Add session id.  */
3017         _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_SESSION_ID, 2, 0);
3018     }
3019 
3020     /* Add length.  */
3021     _nx_pppoe_client_data_add(work_ptr + NX_PPPOE_CLIENT_OFFSET_LENGTH, 2, (index - NX_PPPOE_CLIENT_OFFSET_PAYLOAD));
3022 
3023     /* Update the append pointer and length.  */
3024     packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + index;
3025     packet_ptr -> nx_packet_length = index;
3026 
3027     /* Send PPPoE session packet.  */
3028     _nx_pppoe_client_packet_send(pppoe_client_ptr, packet_ptr, NX_LINK_PPPOE_DISCOVERY_SEND);
3029 
3030     /* Return success.  */
3031     return(NX_PPPOE_CLIENT_SUCCESS);
3032 }
3033 
3034 
3035 /**************************************************************************/
3036 /*                                                                        */
3037 /*  FUNCTION                                               RELEASE        */
3038 /*                                                                        */
3039 /*    _nx_pppoe_client_packet_send                        PORTABLE C      */
3040 /*                                                           6.1          */
3041 /*  AUTHOR                                                                */
3042 /*                                                                        */
3043 /*    Yuxin Zhou, Microsoft Corporation                                   */
3044 /*                                                                        */
3045 /*  DESCRIPTION                                                           */
3046 /*                                                                        */
3047 /*    This function sends a PPPoE packet to the appropriate link driver.  */
3048 /*                                                                        */
3049 /*  INPUT                                                                 */
3050 /*                                                                        */
3051 /*    pppoe_client_ptr                      Pointer to PPPoE control block*/
3052 /*    client_session_ptr                    Pointer to Client Session     */
3053 /*    packet_ptr                            Pointer to packet to send     */
3054 /*    command                               Driver command                */
3055 /*                                                                        */
3056 /*  OUTPUT                                                                */
3057 /*                                                                        */
3058 /*    status                                Completion status             */
3059 /*                                                                        */
3060 /*  CALLS                                                                 */
3061 /*                                                                        */
3062 /*    (ip_link_driver)                      User supplied link driver     */
3063 /*                                                                        */
3064 /*  CALLED BY                                                             */
3065 /*                                                                        */
3066 /*    _nx_pppoe_client_discovery_send       Send PPPoE Discovery packet   */
3067 /*    _nx_pppoe_client_session_send         Send PPPoE Session packet     */
3068 /*                                                                        */
3069 /*  RELEASE HISTORY                                                       */
3070 /*                                                                        */
3071 /*    DATE              NAME                      DESCRIPTION             */
3072 /*                                                                        */
3073 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3074 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3075 /*                                            resulting in version 6.1    */
3076 /*                                                                        */
3077 /**************************************************************************/
_nx_pppoe_client_packet_send(NX_PPPOE_CLIENT * pppoe_client_ptr,NX_PACKET * packet_ptr,UINT command)3078 static VOID    _nx_pppoe_client_packet_send(NX_PPPOE_CLIENT *pppoe_client_ptr, NX_PACKET *packet_ptr, UINT command)
3079 {
3080 
3081 NX_IP_DRIVER                driver_request;
3082 
3083 
3084     /* Initialize the driver request. */
3085     driver_request.nx_ip_driver_command =               command;
3086     driver_request.nx_ip_driver_ptr =                   pppoe_client_ptr -> nx_pppoe_ip_ptr;
3087     driver_request.nx_ip_driver_packet =                packet_ptr;
3088     driver_request.nx_ip_driver_interface =             pppoe_client_ptr -> nx_pppoe_interface_ptr;
3089 
3090     /* Check if have the server address.  */
3091     if ((pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_msw) ||
3092         (pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_lsw))
3093     {
3094 
3095         /* Set the destination address as server address.  */
3096         driver_request.nx_ip_driver_physical_address_msw = pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_msw;
3097         driver_request.nx_ip_driver_physical_address_lsw = pppoe_client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_lsw;
3098     }
3099     else
3100     {
3101 
3102         /* Set the destination address as boradcast address.  */
3103         driver_request.nx_ip_driver_physical_address_msw = 0x0000FFFF;
3104         driver_request.nx_ip_driver_physical_address_lsw = 0xFFFFFFFF;
3105     }
3106 
3107     /* Sendout the PPPoE packet.  */
3108     (pppoe_client_ptr -> nx_pppoe_link_driver_entry) (&driver_request);
3109 }
3110 
3111 
3112 /**************************************************************************/
3113 /*                                                                        */
3114 /*  FUNCTION                                               RELEASE        */
3115 /*                                                                        */
3116 /*    _nx_pppoe_client_data_get                           PORTABLE C      */
3117 /*                                                           6.1          */
3118 /*  AUTHOR                                                                */
3119 /*                                                                        */
3120 /*    Yuxin Zhou, Microsoft Corporation                                   */
3121 /*                                                                        */
3122 /*  DESCRIPTION                                                           */
3123 /*                                                                        */
3124 /*    This function gets the datas of PPPoE packet.                       */
3125 /*                                                                        */
3126 /*  INPUT                                                                 */
3127 /*                                                                        */
3128 /*    data                                  Pointer to buffer data        */
3129 /*    size                                  Size of data value            */
3130 /*                                                                        */
3131 /*  OUTPUT                                                                */
3132 /*                                                                        */
3133 /*    status                                Completion status             */
3134 /*                                                                        */
3135 /*  CALLS                                                                 */
3136 /*                                                                        */
3137 /*    None                                                                */
3138 /*                                                                        */
3139 /*  CALLED BY                                                             */
3140 /*                                                                        */
3141 /*    _nx_pppoe_client_packet_receive       Receive the PPPoE packet      */
3142 /*    _nx_pppoe_client_discovery_packet_process                           */
3143 /*                                          Process PPPoE Discovery packet*/
3144 /*    _nx_pppoe_client_session_packet_process                             */
3145 /*                                          Process PPPoE Session packet  */
3146 /*    _nx_pppoe_client_tag_process          Process PPPoE TAGs            */
3147 /*                                                                        */
3148 /*  RELEASE HISTORY                                                       */
3149 /*                                                                        */
3150 /*    DATE              NAME                      DESCRIPTION             */
3151 /*                                                                        */
3152 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3153 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3154 /*                                            resulting in version 6.1    */
3155 /*                                                                        */
3156 /**************************************************************************/
_nx_pppoe_client_data_get(UCHAR * data,UINT size)3157 static ULONG  _nx_pppoe_client_data_get(UCHAR *data, UINT size)
3158 {
3159 
3160 ULONG   value = 0;
3161 
3162 
3163     /* Process the data retrieval request.  */
3164     while (size-- > 0)
3165     {
3166 
3167         /* Build return value.  */
3168         value = (value << 8) | *data++;
3169     }
3170 
3171     /* Return value.  */
3172     return(value);
3173 }
3174 
3175 
3176 /**************************************************************************/
3177 /*                                                                        */
3178 /*  FUNCTION                                               RELEASE        */
3179 /*                                                                        */
3180 /*    _nx_pppoe_client_data_add                           PORTABLE C      */
3181 /*                                                           6.1          */
3182 /*  AUTHOR                                                                */
3183 /*                                                                        */
3184 /*    Yuxin Zhou, Microsoft Corporation                                   */
3185 /*                                                                        */
3186 /*  DESCRIPTION                                                           */
3187 /*                                                                        */
3188 /*    This function adds the datas into PPPoE packet.                     */
3189 /*                                                                        */
3190 /*  INPUT                                                                 */
3191 /*                                                                        */
3192 /*    data                                  Pointer to buffer data        */
3193 /*    size                                  Size of data value            */
3194 /*    value                                 Value to add                  */
3195 /*                                                                        */
3196 /*  OUTPUT                                                                */
3197 /*                                                                        */
3198 /*    status                                Completion status             */
3199 /*                                                                        */
3200 /*  CALLS                                                                 */
3201 /*                                                                        */
3202 /*    None                                                                */
3203 /*                                                                        */
3204 /*  CALLED BY                                                             */
3205 /*                                                                        */
3206 /*    _nx_pppoe_client_discovery_send       Send PPPoE Discovery packet   */
3207 /*    _nx_pppoe_client_session_send         Send PPPoE Session packet     */
3208 /*    _nx_pppoe_client_tag_string_add       Add PPPoE string TAG          */
3209 /*                                                                        */
3210 /*  RELEASE HISTORY                                                       */
3211 /*                                                                        */
3212 /*    DATE              NAME                      DESCRIPTION             */
3213 /*                                                                        */
3214 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3215 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3216 /*                                            resulting in version 6.1    */
3217 /*                                                                        */
3218 /**************************************************************************/
_nx_pppoe_client_data_add(UCHAR * data,UINT size,ULONG value)3219 static VOID  _nx_pppoe_client_data_add(UCHAR *data, UINT size, ULONG value)
3220 {
3221 
3222     /* Make sure that data is left justified.  */
3223     switch (size)
3224     {
3225 
3226         case 1:
3227 
3228             value <<= 24;
3229             break;
3230 
3231         case 2:
3232 
3233             value <<= 16;
3234             break;
3235 
3236         case 3:
3237 
3238             value <<= 8;
3239             break;
3240 
3241         default:
3242             break;
3243     }
3244 
3245     /* Store the value.  */
3246     while (size-- > 0)
3247     {
3248 
3249         *data = (UCHAR) ((value >> 24) & 0xff);
3250         data++;
3251         value <<= 8;
3252     }
3253 }
3254 
3255 
3256 /**************************************************************************/
3257 /*                                                                        */
3258 /*  FUNCTION                                               RELEASE        */
3259 /*                                                                        */
3260 /*    _nx_pppoe_client_string_add                         PORTABLE C      */
3261 /*                                                           6.1          */
3262 /*  AUTHOR                                                                */
3263 /*                                                                        */
3264 /*    Yuxin Zhou, Microsoft Corporation                                   */
3265 /*                                                                        */
3266 /*  DESCRIPTION                                                           */
3267 /*                                                                        */
3268 /*    This function adds the string into PPPoE packet.                    */
3269 /*                                                                        */
3270 /*  INPUT                                                                 */
3271 /*                                                                        */
3272 /*    dest                                  Pointer to destination buffer */
3273 /*    source                                Pointer to source buffer      */
3274 /*    size                                  Number of bytes to add        */
3275 /*                                                                        */
3276 /*  OUTPUT                                                                */
3277 /*                                                                        */
3278 /*    status                                Completion status             */
3279 /*                                                                        */
3280 /*  CALLS                                                                 */
3281 /*                                                                        */
3282 /*    None                                                                */
3283 /*                                                                        */
3284 /*  CALLED BY                                                             */
3285 /*                                                                        */
3286 /*    _nx_pppoe_client_tag_string_add       Add PPPoE string TAG          */
3287 /*                                                                        */
3288 /*  RELEASE HISTORY                                                       */
3289 /*                                                                        */
3290 /*    DATE              NAME                      DESCRIPTION             */
3291 /*                                                                        */
3292 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3293 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3294 /*                                            resulting in version 6.1    */
3295 /*                                                                        */
3296 /**************************************************************************/
_nx_pppoe_client_string_add(UCHAR * dest,UCHAR * source,UINT size)3297 static VOID  _nx_pppoe_client_string_add(UCHAR *dest, UCHAR *source, UINT size)
3298 {
3299 
3300     /* Loop to copy all bytes.  */
3301     while (size-- > 0)
3302     {
3303 
3304         /* Copy a byte.  */
3305         *dest++ = *source++;
3306     }
3307 }
3308 
3309 
3310 /**************************************************************************/
3311 /*                                                                        */
3312 /*  FUNCTION                                               RELEASE        */
3313 /*                                                                        */
3314 /*    _nx_pppoe_client_tag_string_add                     PORTABLE C      */
3315 /*                                                           6.1          */
3316 /*  AUTHOR                                                                */
3317 /*                                                                        */
3318 /*    Yuxin Zhou, Microsoft Corporation                                   */
3319 /*                                                                        */
3320 /*  DESCRIPTION                                                           */
3321 /*                                                                        */
3322 /*    This function adds the TAG with string into PPPoE packet.           */
3323 /*                                                                        */
3324 /*  INPUT                                                                 */
3325 /*                                                                        */
3326 /*    data_ptr                              Pointer to data buffer        */
3327 /*    tag_type                              Type of TAG                   */
3328 /*    tag_length                            Length of TAG                 */
3329 /*    tag_value_string                      String value of TAG to add    */
3330 /*    index                                 Location into data buffer     */
3331 /*                                             to write data              */
3332 /*                                                                        */
3333 /*  OUTPUT                                                                */
3334 /*                                                                        */
3335 /*    status                                Completion status             */
3336 /*                                                                        */
3337 /*  CALLS                                                                 */
3338 /*                                                                        */
3339 /*    _nx_pppoe_client_data_add             Add PPPoE data                */
3340 /*    _nx_pppoe_client_string_add           Add PPPoE string data         */
3341 /*                                                                        */
3342 /*  CALLED BY                                                             */
3343 /*                                                                        */
3344 /*    _nx_pppoe_client_discovery_send       Send PPPoE Discovery packet   */
3345 /*                                                                        */
3346 /*  RELEASE HISTORY                                                       */
3347 /*                                                                        */
3348 /*    DATE              NAME                      DESCRIPTION             */
3349 /*                                                                        */
3350 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3351 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3352 /*                                            resulting in version 6.1    */
3353 /*                                                                        */
3354 /**************************************************************************/
_nx_pppoe_client_tag_string_add(UCHAR * data_ptr,UINT tag_type,UINT tag_length,UCHAR * tag_value_string,UINT * index)3355 static UINT  _nx_pppoe_client_tag_string_add(UCHAR *data_ptr, UINT tag_type, UINT tag_length, UCHAR *tag_value_string, UINT *index)
3356 {
3357 
3358     /* Add the tag type.  */
3359     _nx_pppoe_client_data_add(data_ptr + (*index), 2, tag_type);
3360     (*index) += 2;
3361 
3362     /* Add the tag length.  */
3363     _nx_pppoe_client_data_add(data_ptr + (*index), 2, tag_length);
3364     (*index) += 2;
3365 
3366     /* Add the tag value string.  */
3367     _nx_pppoe_client_string_add(data_ptr + (*index), tag_value_string, tag_length);
3368     (*index) += tag_length;
3369 
3370     /* Return a successful completion.  */
3371     return(NX_PPPOE_CLIENT_SUCCESS);
3372 }
3373 
3374 
3375 /**************************************************************************/
3376 /*                                                                        */
3377 /*  FUNCTION                                               RELEASE        */
3378 /*                                                                        */
3379 /*    _nx_pppoe_client_session_cleanup                    PORTABLE C      */
3380 /*                                                           6.1          */
3381 /*  AUTHOR                                                                */
3382 /*                                                                        */
3383 /*    Yuxin Zhou, Microsoft Corporation                                   */
3384 /*                                                                        */
3385 /*  DESCRIPTION                                                           */
3386 /*                                                                        */
3387 /*    This function cleans up the PPPoE session.                          */
3388 /*                                                                        */
3389 /*  INPUT                                                                 */
3390 /*                                                                        */
3391 /*    client_session_ptr                    Pointer to Client Session     */
3392 /*                                                                        */
3393 /*  OUTPUT                                                                */
3394 /*                                                                        */
3395 /*    status                                Completion status             */
3396 /*                                                                        */
3397 /*  CALLS                                                                 */
3398 /*                                                                        */
3399 /*    None                                                                */
3400 /*                                                                        */
3401 /*  CALLED BY                                                             */
3402 /*                                                                        */
3403 /*    _nx_pppoe_client_session_terminate    Terminate the PPPoE session   */
3404 /*    _nx_pppoe_client_session_packet_process                             */
3405 /*                                          Process PPPoE Session packet  */
3406 /*                                                                        */
3407 /*  RELEASE HISTORY                                                       */
3408 /*                                                                        */
3409 /*    DATE              NAME                      DESCRIPTION             */
3410 /*                                                                        */
3411 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3412 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3413 /*                                            resulting in version 6.1    */
3414 /*                                                                        */
3415 /**************************************************************************/
_nx_pppoe_client_session_cleanup(NX_PPPOE_CLIENT * client_ptr)3416 static UINT  _nx_pppoe_client_session_cleanup(NX_PPPOE_CLIENT *client_ptr)
3417 {
3418 
3419     /* Cleanup the state.  */
3420     client_ptr -> nx_pppoe_state = NX_PPPOE_CLIENT_STATE_INITIAL;
3421 
3422     /* Ceanup the tags.  */
3423     client_ptr -> nx_pppoe_ac_name_size = 0;
3424     client_ptr -> nx_pppoe_ac_cookie_size = 0;
3425     client_ptr -> nx_pppoe_relay_session_id_size = 0;
3426 
3427     /* Cleanup the server information.  */
3428     client_ptr -> nx_pppoe_server_session.nx_pppoe_session_id = NX_NULL;
3429     client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_msw = NX_NULL;
3430     client_ptr -> nx_pppoe_server_session.nx_pppoe_physical_address_lsw = NX_NULL;
3431 
3432     /* Return success.  */
3433     return(NX_PPPOE_CLIENT_SUCCESS);
3434 }
3435 
3436 
3437 /**************************************************************************/
3438 /*                                                                        */
3439 /*  FUNCTION                                               RELEASE        */
3440 /*                                                                        */
3441 /*    _nx_pppoe_client_session_thread_suspend             PORTABLE C      */
3442 /*                                                           6.1          */
3443 /*  AUTHOR                                                                */
3444 /*                                                                        */
3445 /*    Yuxin Zhou, Microsoft Corporation                                   */
3446 /*                                                                        */
3447 /*  DESCRIPTION                                                           */
3448 /*                                                                        */
3449 /*    This function suspends a thread on a PPPoE Session connect service  */
3450 /*                                                                        */
3451 /*  INPUT                                                                 */
3452 /*                                                                        */
3453 /*    suspension_list_head                  Pointer to the suspension list*/
3454 /*    mutex_ptr                             Pointer to mutex to release   */
3455 /*    suspend_cleanup                       Suspension cleanup routine    */
3456 /*    wait_option                           Optional timeout value        */
3457 /*                                                                        */
3458 /*  OUTPUT                                                                */
3459 /*                                                                        */
3460 /*    None                                                                */
3461 /*                                                                        */
3462 /*  CALLS                                                                 */
3463 /*                                                                        */
3464 /*    tx_mutex_put                          Release protection            */
3465 /*    _tx_thread_system_suspend             Suspend thread                */
3466 /*                                                                        */
3467 /*  CALLED BY                                                             */
3468 /*                                                                        */
3469 /*                                                                        */
3470 /*  RELEASE HISTORY                                                       */
3471 /*                                                                        */
3472 /*    DATE              NAME                      DESCRIPTION             */
3473 /*                                                                        */
3474 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3475 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3476 /*                                            resulting in version 6.1    */
3477 /*                                                                        */
3478 /**************************************************************************/
_nx_pppoe_client_session_thread_suspend(TX_THREAD ** suspension_list_head,VOID (* suspend_cleanup)(TX_THREAD * NX_CLEANUP_PARAMETER),NX_PPPOE_CLIENT * pppoe_client_ptr,TX_MUTEX * mutex_ptr,ULONG wait_option)3479 static VOID  _nx_pppoe_client_session_thread_suspend(TX_THREAD **suspension_list_head, VOID (*suspend_cleanup)(TX_THREAD * NX_CLEANUP_PARAMETER),
3480                                                      NX_PPPOE_CLIENT *pppoe_client_ptr, TX_MUTEX *mutex_ptr, ULONG wait_option)
3481 {
3482 
3483 TX_INTERRUPT_SAVE_AREA
3484 
3485 TX_THREAD *thread_ptr;
3486 
3487 
3488     /* Disable interrupts.  */
3489     TX_DISABLE
3490 
3491     /* Pickup thread pointer.  */
3492     thread_ptr =  _tx_thread_current_ptr;
3493 
3494     /* Setup suspension list.  */
3495     if (*suspension_list_head)
3496     {
3497 
3498         /* This list is not NULL, add current thread to the end. */
3499         thread_ptr -> tx_thread_suspended_next =      *suspension_list_head;
3500         thread_ptr -> tx_thread_suspended_previous =  (*suspension_list_head) -> tx_thread_suspended_previous;
3501         ((*suspension_list_head) -> tx_thread_suspended_previous) -> tx_thread_suspended_next =  thread_ptr;
3502         (*suspension_list_head) -> tx_thread_suspended_previous =   thread_ptr;
3503     }
3504     else
3505     {
3506 
3507         /* No other threads are suspended.  Setup the head pointer and
3508            just setup this threads pointers to itself.  */
3509         *suspension_list_head =  thread_ptr;
3510         thread_ptr -> tx_thread_suspended_next =        thread_ptr;
3511         thread_ptr -> tx_thread_suspended_previous =    thread_ptr;
3512     }
3513 
3514     /* Setup cleanup routine pointer.  */
3515     thread_ptr -> tx_thread_suspend_cleanup =  suspend_cleanup;
3516 
3517     /* Setup cleanup information, i.e. this pool control
3518        block.  */
3519     thread_ptr -> tx_thread_suspend_control_block =  (void *)pppoe_client_ptr;
3520 
3521     /* Set the state to suspended.  */
3522     thread_ptr -> tx_thread_state =  TX_TCP_IP;
3523 
3524     /* Set the suspending flag.  */
3525     thread_ptr -> tx_thread_suspending =  TX_TRUE;
3526 
3527     /* Temporarily disable preemption.  */
3528     _tx_thread_preempt_disable++;
3529 
3530     /* Save the timeout value.  */
3531     thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks =  wait_option;
3532 
3533     /* Restore interrupts.  */
3534     TX_RESTORE
3535 
3536     /* Release protection.  */
3537     tx_mutex_put(mutex_ptr);
3538 
3539     /* Call actual thread suspension routine.  */
3540     _tx_thread_system_suspend(thread_ptr);
3541 }
3542 
3543 
3544 /**************************************************************************/
3545 /*                                                                        */
3546 /*  FUNCTION                                               RELEASE        */
3547 /*                                                                        */
3548 /*    _nx_pppoe_client_session_thread_resume              PORTABLE C      */
3549 /*                                                           6.1          */
3550 /*  AUTHOR                                                                */
3551 /*                                                                        */
3552 /*    Yuxin Zhou, Microsoft Corporation                                   */
3553 /*                                                                        */
3554 /*  DESCRIPTION                                                           */
3555 /*                                                                        */
3556 /*    This function resumes a thread suspended on a PPPoE Client session  */
3557 /*    connect service.                                                    */
3558 /*                                                                        */
3559 /*  INPUT                                                                 */
3560 /*                                                                        */
3561 /*    thread_ptr                            Pointer to thread to resume   */
3562 /*    status                                Return status                 */
3563 /*                                                                        */
3564 /*  OUTPUT                                                                */
3565 /*                                                                        */
3566 /*    None                                                                */
3567 /*                                                                        */
3568 /*  CALLS                                                                 */
3569 /*                                                                        */
3570 /*    _tx_thread_system_resume              Resume suspended thread       */
3571 /*                                                                        */
3572 /*  CALLED BY                                                             */
3573 /*                                                                        */
3574 /*                                                                        */
3575 /*  RELEASE HISTORY                                                       */
3576 /*                                                                        */
3577 /*    DATE              NAME                      DESCRIPTION             */
3578 /*                                                                        */
3579 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3580 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3581 /*                                            resulting in version 6.1    */
3582 /*                                                                        */
3583 /**************************************************************************/
_nx_pppoe_client_session_thread_resume(TX_THREAD ** suspension_list_head,UINT status)3584 VOID  _nx_pppoe_client_session_thread_resume(TX_THREAD **suspension_list_head, UINT status)
3585 {
3586 
3587 TX_INTERRUPT_SAVE_AREA
3588 
3589 TX_THREAD *thread_ptr;
3590 
3591 
3592     /* Disable interrupts.  */
3593     TX_DISABLE
3594 
3595     /* Pickup the thread pointer.  */
3596     thread_ptr =  *suspension_list_head;
3597 
3598     /* Determine if there still is a thread suspended.  */
3599     if (thread_ptr)
3600     {
3601 
3602         /* Determine if there are anymore threads on the suspension list.  */
3603         if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
3604         {
3605 
3606             /* Only this thread is on the suspension list.  Simply set the
3607                list head to NULL to reflect an empty suspension list.  */
3608             *suspension_list_head =  TX_NULL;
3609         }
3610         else
3611         {
3612 
3613             /* More than one thread is on the suspension list, we need to
3614                adjust the link pointers and move the next entry to the
3615                front of the list.  */
3616             *suspension_list_head =  thread_ptr -> tx_thread_suspended_next;
3617 
3618             /* Update the links of the adjacent threads.  */
3619             (thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
3620                 thread_ptr -> tx_thread_suspended_previous;
3621             (thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
3622                 thread_ptr -> tx_thread_suspended_next;
3623         }
3624 
3625         /* Prepare for resumption of the thread.  */
3626 
3627         /* Clear cleanup routine to avoid timeout.  */
3628         thread_ptr -> tx_thread_suspend_cleanup =  TX_NULL;
3629 
3630         /* Temporarily disable preemption.  */
3631         _tx_thread_preempt_disable++;
3632 
3633         /* Restore interrupts.  */
3634         TX_RESTORE
3635 
3636         /* Put return status into the thread control block.  */
3637         thread_ptr -> tx_thread_suspend_status =  status;
3638 
3639         /* Resume thread.  */
3640         _tx_thread_system_resume(thread_ptr);
3641     }
3642     else
3643     {
3644 
3645         /* Nothing was suspended.  Simply restore interrupts.  */
3646         TX_RESTORE
3647     }
3648 }
3649 
3650 
3651 /**************************************************************************/
3652 /*                                                                        */
3653 /*  FUNCTION                                               RELEASE        */
3654 /*                                                                        */
3655 /*    _nx_pppoe_client_session_connect_cleanup            PORTABLE C      */
3656 /*                                                           6.1          */
3657 /*  AUTHOR                                                                */
3658 /*                                                                        */
3659 /*    Yuxin Zhou, Microsoft Corporation                                   */
3660 /*                                                                        */
3661 /*  DESCRIPTION                                                           */
3662 /*                                                                        */
3663 /*    This function processes PPPoE connect timeout and thread terminate  */
3664 /*    actions that require the PPPoE Client data structures to be cleaned */
3665 /*    up.                                                                 */
3666 /*                                                                        */
3667 /*  INPUT                                                                 */
3668 /*                                                                        */
3669 /*    thread_ptr                            Pointer to suspended thread's */
3670 /*                                            control block               */
3671 /*                                                                        */
3672 /*  OUTPUT                                                                */
3673 /*                                                                        */
3674 /*    None                                                                */
3675 /*                                                                        */
3676 /*  CALLS                                                                 */
3677 /*                                                                        */
3678 /*    tx_event_flags_set                    Set event flag                */
3679 /*    _tx_thread_system_resume              Resume thread service         */
3680 /*                                                                        */
3681 /*  CALLED BY                                                             */
3682 /*                                                                        */
3683 /*                                                                        */
3684 /*  RELEASE HISTORY                                                       */
3685 /*                                                                        */
3686 /*    DATE              NAME                      DESCRIPTION             */
3687 /*                                                                        */
3688 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3689 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3690 /*                                            resulting in version 6.1    */
3691 /*                                                                        */
3692 /**************************************************************************/
_nx_pppoe_client_session_connect_cleanup(TX_THREAD * thread_ptr NX_CLEANUP_PARAMETER)3693 static VOID  _nx_pppoe_client_session_connect_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER)
3694 {
3695 
3696 TX_INTERRUPT_SAVE_AREA
3697 
3698 NX_PPPOE_CLIENT *pppoe_client_ptr;      /* Working PPPoE Client pointer  */
3699 
3700     NX_CLEANUP_EXTENSION
3701 
3702     /* Disable interrupts.  */
3703     TX_DISABLE
3704 
3705     /* Setup pointer to PPPoE Client control block.  */
3706     pppoe_client_ptr =  (NX_PPPOE_CLIENT *)thread_ptr -> tx_thread_suspend_control_block;
3707 
3708     /* Determine if the PPPoE Client pointer is valid.  */
3709     if ((!pppoe_client_ptr) || (pppoe_client_ptr -> nx_pppoe_id != NX_PPPOE_CLIENT_ID))
3710     {
3711 
3712         /* Restore interrupts.  */
3713         TX_RESTORE
3714 
3715         return;
3716     }
3717 
3718     /* Determine if the cleanup is still required.  */
3719     if (!(thread_ptr -> tx_thread_suspend_cleanup))
3720     {
3721 
3722         /* Restore interrupts.  */
3723         TX_RESTORE
3724 
3725         return;
3726     }
3727 
3728     /* Determine if the caller is an ISR or the system timer thread.  */
3729 #ifndef TX_TIMER_PROCESS_IN_ISR
3730     if ((TX_THREAD_GET_SYSTEM_STATE()) || (_tx_thread_current_ptr == &_tx_timer_thread))
3731 #else
3732     if (TX_THREAD_GET_SYSTEM_STATE())
3733 #endif
3734     {
3735 
3736         /* Yes, defer the processing to the PPPoE Client thread.  */
3737 
3738         /* Restore interrupts.  */
3739         TX_RESTORE
3740 
3741         /* Set the deferred cleanup flag for the IP thread.  */
3742         tx_event_flags_set(&(pppoe_client_ptr -> nx_pppoe_events), NX_PPPOE_CLIENT_SESSION_CONNECT_CLEANUP_EVENT, TX_OR);
3743 
3744         /* Return to caller.  */
3745         return;
3746     }
3747     else
3748     {
3749 
3750         /* Yes, we still have thread suspension!  */
3751 
3752         /* Clear the suspension cleanup flag.  */
3753         thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
3754 
3755         /* Clear the suspension pointer.   */
3756         pppoe_client_ptr -> nx_pppoe_session_connect_suspended_thread = NX_NULL;
3757 
3758         /* Cleanup the PPPoE session.  */
3759         _nx_pppoe_client_session_cleanup(pppoe_client_ptr);
3760 
3761         /* Now we need to determine if this cleanup is from a terminate, timeout,
3762            or from a wait abort.  */
3763         if (thread_ptr -> tx_thread_state == TX_TCP_IP)
3764         {
3765 
3766             /* Thread still suspended on the PPPoE Client.  Setup return error status and
3767                resume the thread.  */
3768 
3769             /* Setup return status.  */
3770             thread_ptr -> tx_thread_suspend_status = NX_PPPOE_CLIENT_SESSION_NOT_ESTABLISHED;
3771 
3772             /* Temporarily disable preemption.  */
3773             _tx_thread_preempt_disable++;
3774 
3775             /* Restore interrupts.  */
3776             TX_RESTORE
3777 
3778             /* Resume the thread!  Check for preemption even though we are executing
3779                from the system timer thread right now which normally executes at the
3780                highest priority.  */
3781             _tx_thread_system_resume(thread_ptr);
3782 
3783             /* Finished, just return.  */
3784             return;
3785         }
3786     }
3787 
3788     /* Restore interrupts.  */
3789     TX_RESTORE
3790 }
3791 #endif /* NX_DISABLE_IPV4 */
3792 
3793