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