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_SERVER_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_pppoe_server.h"
46 #include "nx_packet.h"
47 
48 /* Define the PPPoE created list head pointer and count.  */
49 NX_PPPOE_SERVER  *_nx_pppoe_server_created_ptr = NX_NULL;
50 
51 
52 /* Define internal PPPoE services. */
53 
54 static VOID    _nx_pppoe_server_thread_entry(ULONG pppoe_server_ptr_value);
55 static VOID    _nx_pppoe_server_packet_receive(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PACKET *packet_ptr);
56 static VOID    _nx_pppoe_server_discovery_packet_process(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PACKET *packet_ptr, ULONG client_mac_msw, ULONG client_mac_lsw, UINT is_broadcast);
57 static VOID    _nx_pppoe_server_session_packet_process(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PACKET *packet_ptr, ULONG client_mac_msw, ULONG client_mac_lsw);
58 static UINT    _nx_pppoe_server_discovery_send(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PPPOE_CLIENT_SESSION *client_session_ptr, UINT code);
59 static VOID    _nx_pppoe_server_packet_send(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PPPOE_CLIENT_SESSION *client_session_ptr, NX_PACKET *packet_ptr, UINT command);
60 static UINT    _nx_pppoe_server_tag_process(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PPPOE_CLIENT_SESSION *client_session_ptr, UINT code, UCHAR *tag_ptr, ULONG length);
61 static ULONG   _nx_pppoe_server_data_get(UCHAR *data, UINT size);
62 static VOID    _nx_pppoe_server_data_add(UCHAR *data, UINT size, ULONG value);
63 static VOID    _nx_pppoe_server_string_add(UCHAR *dest, UCHAR *source, UINT size);
64 static UINT    _nx_pppoe_server_tag_string_add(UCHAR *data_ptr, UINT tag_type, UINT tag_length,  UCHAR *tag_value_string, UINT *index);
65 static UINT    _nx_pppoe_server_session_find(NX_PPPOE_SERVER *pppoe_server_ptr, ULONG client_mac_msw, ULONG client_mac_lsw,
66                                              ULONG session_id, UINT *session_index, NX_PPPOE_CLIENT_SESSION **client_session_ptr);
67 static UINT    _nx_pppoe_server_session_cleanup(NX_PPPOE_CLIENT_SESSION *client_session_ptr);
68 
69 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
70 static UCHAR   *nx_pppoe_service_name[1];
71 #endif
72 
73 /**************************************************************************/
74 /*                                                                        */
75 /*  FUNCTION                                               RELEASE        */
76 /*                                                                        */
77 /*    _nxe_pppoe_server_create                            PORTABLE C      */
78 /*                                                           6.1          */
79 /*  AUTHOR                                                                */
80 /*                                                                        */
81 /*    Yuxin Zhou, Microsoft Corporation                                   */
82 /*                                                                        */
83 /*  DESCRIPTION                                                           */
84 /*                                                                        */
85 /*    This function checks for errors in the PPPoE Server instance create */
86 /*    function call.                                                      */
87 /*                                                                        */
88 /*  INPUT                                                                 */
89 /*                                                                        */
90 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
91 /*    name                                  Name of this PPPoE instance   */
92 /*    ip_ptr                                Pointer to IP control block   */
93 /*    interface_index                       IP Interface Index            */
94 /*    pppoe_link_driver                     User supplied link driver     */
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 /*                                                                        */
100 /*  OUTPUT                                                                */
101 /*                                                                        */
102 /*    status                                Completion status             */
103 /*                                                                        */
104 /*  CALLS                                                                 */
105 /*                                                                        */
106 /*    _nx_pppoe_server_create               Actual PPPoE instance create  */
107 /*                                            function                    */
108 /*                                                                        */
109 /*  CALLED BY                                                             */
110 /*                                                                        */
111 /*    Application                                                         */
112 /*                                                                        */
113 /*  RELEASE HISTORY                                                       */
114 /*                                                                        */
115 /*    DATE              NAME                      DESCRIPTION             */
116 /*                                                                        */
117 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
118 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
119 /*                                            resulting in version 6.1    */
120 /*                                                                        */
121 /**************************************************************************/
_nxe_pppoe_server_create(NX_PPPOE_SERVER * pppoe_server_ptr,UCHAR * name,NX_IP * ip_ptr,UINT interface_index,VOID (* pppoe_link_driver)(struct NX_IP_DRIVER_STRUCT *),NX_PACKET_POOL * pool_ptr,VOID * stack_ptr,ULONG stack_size,UINT priority)122 UINT  _nxe_pppoe_server_create(NX_PPPOE_SERVER *pppoe_server_ptr, UCHAR *name, NX_IP *ip_ptr, UINT interface_index,
123                                VOID (*pppoe_link_driver)(struct NX_IP_DRIVER_STRUCT *), NX_PACKET_POOL *pool_ptr,
124                                VOID *stack_ptr, ULONG stack_size, UINT priority)
125 {
126 
127 UINT    status;
128 
129     /* Check for invalid input pointers.  */
130     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id == NX_PPPOE_SERVER_ID) ||
131         (ip_ptr == NX_NULL) || (ip_ptr -> nx_ip_id != NX_IP_ID) ||
132         (pppoe_link_driver == NX_NULL) || (pool_ptr == NX_NULL) ||
133         (pool_ptr -> nx_packet_pool_id != NX_PACKET_POOL_ID) ||
134         (stack_ptr == NX_NULL))
135         return(NX_PPPOE_SERVER_PTR_ERROR);
136 
137     /* Check for invalid interface ID */
138     if(interface_index >= NX_MAX_PHYSICAL_INTERFACES)
139         return(NX_PPPOE_SERVER_INVALID_INTERFACE);
140 
141     /* Check for interface being valid. */
142     if(!ip_ptr -> nx_ip_interface[interface_index].nx_interface_valid)
143         return(NX_PPPOE_SERVER_INVALID_INTERFACE);
144 
145     /* Check for payload size of packet pool.  */
146     if (pool_ptr -> nx_packet_pool_payload_size < NX_PPPOE_SERVER_MIN_PACKET_PAYLOAD_SIZE)
147         return(NX_PPPOE_SERVER_PACKET_PAYLOAD_ERROR);
148 
149     /* Check for a memory size error.  */
150     if (stack_size < TX_MINIMUM_STACK)
151         return(NX_PPPOE_SERVER_MEMORY_SIZE_ERROR);
152 
153     /* Check the priority specified.  */
154     if (priority >= TX_MAX_PRIORITIES)
155         return(NX_PPPOE_SERVER_PRIORITY_ERROR);
156 
157     /* Call actual PPPoE server instance create function.  */
158     status =  _nx_pppoe_server_create(pppoe_server_ptr, name, ip_ptr, interface_index,
159                                       pppoe_link_driver, pool_ptr, stack_ptr, stack_size, priority);
160 
161     /* Return completion status.  */
162     return(status);
163 }
164 
165 
166 /**************************************************************************/
167 /*                                                                        */
168 /*  FUNCTION                                               RELEASE        */
169 /*                                                                        */
170 /*    _nx_pppoe_server_create                             PORTABLE C      */
171 /*                                                           6.1          */
172 /*  AUTHOR                                                                */
173 /*                                                                        */
174 /*    Yuxin Zhou, Microsoft Corporation                                   */
175 /*                                                                        */
176 /*  DESCRIPTION                                                           */
177 /*                                                                        */
178 /*    This function creates an PPPoE Server instance, including setting   */
179 /*    up all appropriate data structures, creating PPPoE event flag       */
180 /*    object and PPPoE thread.                                            */
181 /*                                                                        */
182 /*  INPUT                                                                 */
183 /*                                                                        */
184 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
185 /*    name                                  Name of this PPPoE instance   */
186 /*    ip_ptr                                Pointer to IP control block   */
187 /*    interface_index                       Interface Index               */
188 /*    pppoe_link_driver                     User supplied link driver     */
189 /*    pool_ptr                              packet pool                   */
190 /*    stack_ptr                             Pointer stack area for PPPoE  */
191 /*    stack_size                            Size of PPPoE stack area      */
192 /*    priority                              Priority of PPPoE  thread     */
193 /*                                                                        */
194 /*  OUTPUT                                                                */
195 /*                                                                        */
196 /*    status                                Completion status             */
197 /*                                                                        */
198 /*  CALLS                                                                 */
199 /*                                                                        */
200 /*    tx_event_flags_create                 Create IP event flags         */
201 /*    tx_thread_create                      Create IP helper thread       */
202 /*                                                                        */
203 /*  CALLED BY                                                             */
204 /*                                                                        */
205 /*    Application                                                         */
206 /*                                                                        */
207 /*  RELEASE HISTORY                                                       */
208 /*                                                                        */
209 /*    DATE              NAME                      DESCRIPTION             */
210 /*                                                                        */
211 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
212 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
213 /*                                            resulting in version 6.1    */
214 /*                                                                        */
215 /**************************************************************************/
_nx_pppoe_server_create(NX_PPPOE_SERVER * pppoe_server_ptr,UCHAR * name,NX_IP * ip_ptr,UINT interface_index,VOID (* pppoe_link_driver)(struct NX_IP_DRIVER_STRUCT *),NX_PACKET_POOL * pool_ptr,VOID * stack_ptr,ULONG stack_size,UINT priority)216 UINT  _nx_pppoe_server_create(NX_PPPOE_SERVER *pppoe_server_ptr, UCHAR *name, NX_IP *ip_ptr, UINT interface_index,
217                               VOID (*pppoe_link_driver)(struct NX_IP_DRIVER_STRUCT *), NX_PACKET_POOL *pool_ptr,
218                               VOID *stack_ptr, ULONG stack_size, UINT priority)
219 {
220 
221 TX_INTERRUPT_SAVE_AREA
222 
223 
224     /* Initialize the PPPoE Server control block to zero.  */
225     memset((void *) pppoe_server_ptr, 0, sizeof(NX_PPPOE_SERVER));
226 
227     /* Save the PPPoE name.  */
228     pppoe_server_ptr -> nx_pppoe_name = name;
229 
230     /* Save the length of PPPoE name to avoid compute strlen repeatedly in _nx_pppoe_server_discovery_send.  */
231     if (_nx_utility_string_length_check((char *)pppoe_server_ptr -> nx_pppoe_name,
232                                         &(pppoe_server_ptr -> nx_pppoe_name_length),
233                                         NX_MAX_STRING_LENGTH))
234     {
235         return(NX_PPPOE_SERVER_PTR_ERROR);
236     }
237 
238     /* Save the IP pointer.  */
239     pppoe_server_ptr -> nx_pppoe_ip_ptr = ip_ptr;
240 
241     /* Setup the interface index and interface pointer.  */
242     pppoe_server_ptr -> nx_pppoe_interface_ptr = &(ip_ptr -> nx_ip_interface[interface_index]);
243 
244     /* Save the packet pool pointer.  */
245     pppoe_server_ptr -> nx_pppoe_packet_pool_ptr = pool_ptr;
246 
247     /* Setup the enabled flag.  */
248     pppoe_server_ptr -> nx_pppoe_enabled = NX_FALSE;
249 
250     /* Save the starting Session ID.  */
251     pppoe_server_ptr -> nx_pppoe_session_id = NX_PPPOE_SERVER_START_SESSION_ID;
252 
253     /* Initialize PPPoE notify function pointer */
254     pppoe_server_ptr -> nx_pppoe_discover_initiation_notify = NX_NULL;
255     pppoe_server_ptr -> nx_pppoe_discover_request_notify = NX_NULL;
256     pppoe_server_ptr -> nx_pppoe_discover_terminate_notify = NX_NULL;
257     pppoe_server_ptr -> nx_pppoe_discover_terminate_confirm = NX_NULL;
258     pppoe_server_ptr -> nx_pppoe_data_receive_notify = NX_NULL;
259     pppoe_server_ptr -> nx_pppoe_data_send_notify = NX_NULL;
260 
261     /* Setup the link driver address.  */
262     pppoe_server_ptr -> nx_pppoe_link_driver_entry = pppoe_link_driver;
263 
264     /* Create event flag group to control the PPPoE processing thread.  */
265     tx_event_flags_create(&(pppoe_server_ptr -> nx_pppoe_events), "PPPoE Server EVENTS") ;
266 
267     /* Create the PPPoE processing thread.  */
268     tx_thread_create(&(pppoe_server_ptr -> nx_pppoe_thread), "PPPoE Server THREAD", _nx_pppoe_server_thread_entry, (ULONG) pppoe_server_ptr,
269                      stack_ptr, stack_size, priority, priority, NX_PPPOE_SERVER_THREAD_TIME_SLICE, TX_DONT_START);
270 
271     /* Otherwise, the PPPoE initialization was successful.  Place the
272        PPPoE control block on created PPPoE instance.  */
273     TX_DISABLE
274 
275     /* Load the PPPoE Server ID field in the PPPoE Server control block.  */
276     pppoe_server_ptr -> nx_pppoe_id =  NX_PPPOE_SERVER_ID;
277 
278     /* Set the pointer of global variable PPPoE.  */
279     _nx_pppoe_server_created_ptr = pppoe_server_ptr;
280 
281     /* Restore previous interrupt posture.  */
282     TX_RESTORE
283 
284     /* Return success.  */
285     return(NX_PPPOE_SERVER_SUCCESS);
286 }
287 
288 /**************************************************************************/
289 /*                                                                        */
290 /*  FUNCTION                                               RELEASE        */
291 /*                                                                        */
292 /*    _nxe_pppoe_server_ac_name_set                       PORTABLE C      */
293 /*                                                           6.1          */
294 /*  AUTHOR                                                                */
295 /*                                                                        */
296 /*    Yuxin Zhou, Microsoft Corporation                                   */
297 /*                                                                        */
298 /*  DESCRIPTION                                                           */
299 /*                                                                        */
300 /*    This function checks for errors in the PPPoE Server set Access      */
301 /*    Concentrator name function call.                                    */
302 /*                                                                        */
303 /*  INPUT                                                                 */
304 /*                                                                        */
305 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
306 /*    ac_name                               Access Concentrator name      */
307 /*    ac_name_length                        Length of Name                */
308 /*                                                                        */
309 /*  OUTPUT                                                                */
310 /*                                                                        */
311 /*    status                                Completion status             */
312 /*                                                                        */
313 /*  CALLS                                                                 */
314 /*                                                                        */
315 /*    _nx_pppoe_server_ac_name_set          Set Access Concentrator       */
316 /*                                            name function               */
317 /*                                                                        */
318 /*  CALLED BY                                                             */
319 /*                                                                        */
320 /*    Application                                                         */
321 /*                                                                        */
322 /*  RELEASE HISTORY                                                       */
323 /*                                                                        */
324 /*    DATE              NAME                      DESCRIPTION             */
325 /*                                                                        */
326 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
327 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
328 /*                                            resulting in version 6.1    */
329 /*                                                                        */
330 /**************************************************************************/
_nxe_pppoe_server_ac_name_set(NX_PPPOE_SERVER * pppoe_server_ptr,UCHAR * ac_name,UINT ac_name_length)331 UINT  _nxe_pppoe_server_ac_name_set(NX_PPPOE_SERVER *pppoe_server_ptr, UCHAR *ac_name, UINT ac_name_length)
332 {
333 
334 UINT    status;
335 
336     /* Check for invalid input pointers.  */
337     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
338         return(NX_PPPOE_SERVER_PTR_ERROR);
339 
340     /* Call Access Concentrator name set function.  */
341     status =  _nx_pppoe_server_ac_name_set(pppoe_server_ptr, ac_name, ac_name_length);
342 
343     /* Return completion status.  */
344     return(status);
345 }
346 
347 
348 /**************************************************************************/
349 /*                                                                        */
350 /*  FUNCTION                                               RELEASE        */
351 /*                                                                        */
352 /*    _nx_pppoe_server_ac_name_set                        PORTABLE C      */
353 /*                                                           6.1          */
354 /*  AUTHOR                                                                */
355 /*                                                                        */
356 /*    Yuxin Zhou, Microsoft Corporation                                   */
357 /*                                                                        */
358 /*  DESCRIPTION                                                           */
359 /*                                                                        */
360 /*    This function sets Access Concentrator name function call.          */
361 /*                                                                        */
362 /*    Note: The string of ac_name must be NULL-terminated and length      */
363 /*    of ac_name matches the length specified in the argument list.       */
364 /*                                                                        */
365 /*  INPUT                                                                 */
366 /*                                                                        */
367 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
368 /*    ac_name                               Access Concentrator name      */
369 /*    ac_name_length                        Length of Name                */
370 /*                                                                        */
371 /*  OUTPUT                                                                */
372 /*                                                                        */
373 /*    status                                Completion status             */
374 /*                                                                        */
375 /*  CALLS                                                                 */
376 /*                                                                        */
377 /*    _nx_utility_string_length_check       Check string length           */
378 /*                                                                        */
379 /*  CALLED BY                                                             */
380 /*                                                                        */
381 /*    Application                                                         */
382 /*                                                                        */
383 /*  RELEASE HISTORY                                                       */
384 /*                                                                        */
385 /*    DATE              NAME                      DESCRIPTION             */
386 /*                                                                        */
387 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
388 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
389 /*                                            resulting in version 6.1    */
390 /*                                                                        */
391 /**************************************************************************/
_nx_pppoe_server_ac_name_set(NX_PPPOE_SERVER * pppoe_server_ptr,UCHAR * ac_name,UINT ac_name_length)392 UINT  _nx_pppoe_server_ac_name_set(NX_PPPOE_SERVER *pppoe_server_ptr, UCHAR *ac_name, UINT ac_name_length)
393 {
394 UINT temp_name_length = 0;
395 
396     /* Get the length of ac_name string.  */
397     if (_nx_utility_string_length_check((CHAR*)ac_name, &temp_name_length, ac_name_length))
398         return(NX_SIZE_ERROR);
399 
400     /* Check the name length.  */
401     if (ac_name_length != temp_name_length)
402         return(NX_SIZE_ERROR);
403 
404     /* Obtain the IP internal mutex before processing the IP event.  */
405     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
406 
407     /* Save the nx_pppoe_ac_name.  */
408     pppoe_server_ptr -> nx_pppoe_ac_name = ac_name;
409 
410     /* Save the nx_pppoe_ac_name length. */
411     pppoe_server_ptr -> nx_pppoe_ac_name_length = ac_name_length;
412 
413     /* Release the IP internal mutex.  */
414     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
415 
416     /* Return success.  */
417     return(NX_PPPOE_SERVER_SUCCESS);
418 }
419 
420 
421 /**************************************************************************/
422 /*                                                                        */
423 /*  FUNCTION                                               RELEASE        */
424 /*                                                                        */
425 /*    _nxe_pppoe_server_delete                            PORTABLE C      */
426 /*                                                           6.1          */
427 /*  AUTHOR                                                                */
428 /*                                                                        */
429 /*    Yuxin Zhou, Microsoft Corporation                                   */
430 /*                                                                        */
431 /*  DESCRIPTION                                                           */
432 /*                                                                        */
433 /*    This function checks for errors in the PPPoE Server instance delete */
434 /*    function call.                                                      */
435 /*                                                                        */
436 /*  INPUT                                                                 */
437 /*                                                                        */
438 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
439 /*                                                                        */
440 /*  OUTPUT                                                                */
441 /*                                                                        */
442 /*    status                                Completion status             */
443 /*                                                                        */
444 /*  CALLS                                                                 */
445 /*                                                                        */
446 /*    _nx_pppoe_server_delete               Actual PPPoE instance delete  */
447 /*                                            function                    */
448 /*                                                                        */
449 /*  CALLED BY                                                             */
450 /*                                                                        */
451 /*    Application                                                         */
452 /*                                                                        */
453 /*  RELEASE HISTORY                                                       */
454 /*                                                                        */
455 /*    DATE              NAME                      DESCRIPTION             */
456 /*                                                                        */
457 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
458 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
459 /*                                            resulting in version 6.1    */
460 /*                                                                        */
461 /**************************************************************************/
_nxe_pppoe_server_delete(NX_PPPOE_SERVER * pppoe_server_ptr)462 UINT  _nxe_pppoe_server_delete(NX_PPPOE_SERVER *pppoe_server_ptr)
463 {
464 
465 UINT    status;
466 
467     /* Check for invalid input pointers.  */
468     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
469         return(NX_PPPOE_SERVER_PTR_ERROR);
470 
471     /* Call actual PPPoE server instance delete function.  */
472     status =  _nx_pppoe_server_delete(pppoe_server_ptr);
473 
474     /* Return completion status.  */
475     return(status);
476 }
477 
478 
479 /**************************************************************************/
480 /*                                                                        */
481 /*  FUNCTION                                               RELEASE        */
482 /*                                                                        */
483 /*    _nx_pppoe_server_delete                             PORTABLE C      */
484 /*                                                           6.1          */
485 /*  AUTHOR                                                                */
486 /*                                                                        */
487 /*    Yuxin Zhou, Microsoft Corporation                                   */
488 /*                                                                        */
489 /*  DESCRIPTION                                                           */
490 /*                                                                        */
491 /*    This function deletes an PPPoE Server instance. including deleting  */
492 /*    PPPoE event flag object and PPPoE thread.                           */
493 /*                                                                        */
494 /*  INPUT                                                                 */
495 /*                                                                        */
496 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
497 /*                                                                        */
498 /*  OUTPUT                                                                */
499 /*                                                                        */
500 /*    status                                Completion status             */
501 /*                                                                        */
502 /*  CALLS                                                                 */
503 /*                                                                        */
504 /*    tx_thread_terminate                   Terminate PPPoE helper thread */
505 /*    tx_thread_delete                      Delete PPPoE helper thread    */
506 /*    tx_event_flags_delete                 Delete PPPoE event flags      */
507 /*                                                                        */
508 /*  CALLED BY                                                             */
509 /*                                                                        */
510 /*    Application                                                         */
511 /*                                                                        */
512 /*  RELEASE HISTORY                                                       */
513 /*                                                                        */
514 /*    DATE              NAME                      DESCRIPTION             */
515 /*                                                                        */
516 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
517 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
518 /*                                            resulting in version 6.1    */
519 /*                                                                        */
520 /**************************************************************************/
_nx_pppoe_server_delete(NX_PPPOE_SERVER * pppoe_server_ptr)521 UINT  _nx_pppoe_server_delete(NX_PPPOE_SERVER *pppoe_server_ptr)
522 {
523 
524 TX_INTERRUPT_SAVE_AREA
525 
526 
527     /* Determine if the caller is the PPPoE thread itself. This is not allowed since
528        a thread cannot delete itself in ThreadX.  */
529     if (&pppoe_server_ptr -> nx_pppoe_thread == tx_thread_identify())
530     {
531 
532         /* Invalid caller of this routine, return an error!  */
533         return(NX_CALLER_ERROR);
534     }
535 
536     /* Disable interrupts.  */
537     TX_DISABLE
538 
539     /* Clear the PPPOE ID to show that it is no longer valid.  */
540     pppoe_server_ptr -> nx_pppoe_id =  0;
541     pppoe_server_ptr -> nx_pppoe_enabled = NX_FALSE;
542 
543     /* Clear the created pointer.  */
544     _nx_pppoe_server_created_ptr = NX_NULL;
545 
546     /* Restore previous interrupt posture.  */
547     TX_RESTORE
548 
549     /* Terminate the thread.  */
550     tx_thread_terminate(&(pppoe_server_ptr -> nx_pppoe_thread));
551 
552     /* Delete the PPPoE thread.  */
553     tx_thread_delete(&(pppoe_server_ptr -> nx_pppoe_thread));
554 
555     /* Delete the event flag group.  */
556     tx_event_flags_delete(&(pppoe_server_ptr -> nx_pppoe_events));
557 
558     /* Return success.  */
559     return(NX_PPPOE_SERVER_SUCCESS);
560 }
561 
562 
563 /**************************************************************************/
564 /*                                                                        */
565 /*  FUNCTION                                               RELEASE        */
566 /*                                                                        */
567 /*    _nxe_pppoe_server_enable                            PORTABLE C      */
568 /*                                                           6.1          */
569 /*  AUTHOR                                                                */
570 /*                                                                        */
571 /*    Yuxin Zhou, Microsoft Corporation                                   */
572 /*                                                                        */
573 /*  DESCRIPTION                                                           */
574 /*                                                                        */
575 /*    This function checks for errors in the PPPoE Server enable function */
576 /*    call.                                                               */
577 /*                                                                        */
578 /*  INPUT                                                                 */
579 /*                                                                        */
580 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
581 /*                                                                        */
582 /*  OUTPUT                                                                */
583 /*                                                                        */
584 /*    status                                Completion status             */
585 /*                                                                        */
586 /*  CALLS                                                                 */
587 /*                                                                        */
588 /*    _nx_pppoe_server_enable               Actual PPPoE enable function  */
589 /*                                                                        */
590 /*  CALLED BY                                                             */
591 /*                                                                        */
592 /*    Application                                                         */
593 /*                                                                        */
594 /*  RELEASE HISTORY                                                       */
595 /*                                                                        */
596 /*    DATE              NAME                      DESCRIPTION             */
597 /*                                                                        */
598 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
599 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
600 /*                                            resulting in version 6.1    */
601 /*                                                                        */
602 /**************************************************************************/
_nxe_pppoe_server_enable(NX_PPPOE_SERVER * pppoe_server_ptr)603 UINT  _nxe_pppoe_server_enable(NX_PPPOE_SERVER *pppoe_server_ptr)
604 {
605 
606 UINT    status;
607 
608     /* Check for invalid input pointers.  */
609     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
610         return(NX_PPPOE_SERVER_PTR_ERROR);
611 
612     /* Make sure the data receive callback function is set before enable.
613        Setting this function by nx_pppoe_server_callback_notify_set() API.  */
614     if (pppoe_server_ptr -> nx_pppoe_data_receive_notify == NX_NULL)
615         return(NX_PPPOE_SERVER_PTR_ERROR);
616 
617     /* Call actual PPPoE server instance enable function.  */
618     status =  _nx_pppoe_server_enable(pppoe_server_ptr);
619 
620     /* Return completion status.  */
621     return(status);
622 }
623 
624 
625 /**************************************************************************/
626 /*                                                                        */
627 /*  FUNCTION                                               RELEASE        */
628 /*                                                                        */
629 /*    _nx_pppoe_server_enable                             PORTABLE C      */
630 /*                                                           6.1          */
631 /*  AUTHOR                                                                */
632 /*                                                                        */
633 /*    Yuxin Zhou, Microsoft Corporation                                   */
634 /*                                                                        */
635 /*  DESCRIPTION                                                           */
636 /*                                                                        */
637 /*    This function enables the PPPoE Server feature.                     */
638 /*                                                                        */
639 /*  INPUT                                                                 */
640 /*                                                                        */
641 /*    tx_mutex_get                          Obtain a protection mutex     */
642 /*    tx_mutex_put                          Release protection mutex      */
643 /*    tx_thread_resume                      Resume PPPoE helper thread    */
644 /*                                                                        */
645 /*  OUTPUT                                                                */
646 /*                                                                        */
647 /*    status                                Completion status             */
648 /*                                                                        */
649 /*  CALLS                                                                 */
650 /*                                                                        */
651 /*    _nx_pppoe_server_enable               Actual PPPoE enable function  */
652 /*                                                                        */
653 /*  CALLED BY                                                             */
654 /*                                                                        */
655 /*    Application                                                         */
656 /*                                                                        */
657 /*  RELEASE HISTORY                                                       */
658 /*                                                                        */
659 /*    DATE              NAME                      DESCRIPTION             */
660 /*                                                                        */
661 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
662 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
663 /*                                            resulting in version 6.1    */
664 /*                                                                        */
665 /**************************************************************************/
_nx_pppoe_server_enable(NX_PPPOE_SERVER * pppoe_server_ptr)666 UINT  _nx_pppoe_server_enable(NX_PPPOE_SERVER *pppoe_server_ptr)
667 {
668 
669     /* Obtain the IP internal mutex before processing the IP event.  */
670     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
671 
672     /* Set the enabled flag.  */
673     pppoe_server_ptr -> nx_pppoe_enabled = NX_TRUE;
674 
675     /* Resume the PPPoE server thread.  */
676     tx_thread_resume(&(pppoe_server_ptr -> nx_pppoe_thread));
677 
678     /* Release the IP internal mutex.  */
679     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
680 
681     /* Return success.  */
682     return(NX_PPPOE_SERVER_SUCCESS);
683 }
684 
685 
686 /**************************************************************************/
687 /*                                                                        */
688 /*  FUNCTION                                               RELEASE        */
689 /*                                                                        */
690 /*    _nxe_pppoe_server_disable                           PORTABLE C      */
691 /*                                                           6.1          */
692 /*  AUTHOR                                                                */
693 /*                                                                        */
694 /*    Yuxin Zhou, Microsoft Corporation                                   */
695 /*                                                                        */
696 /*  DESCRIPTION                                                           */
697 /*                                                                        */
698 /*    This function checks for errors in the PPPoE Server disable function*/
699 /*    call.                                                               */
700 /*                                                                        */
701 /*  INPUT                                                                 */
702 /*                                                                        */
703 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
704 /*                                                                        */
705 /*  OUTPUT                                                                */
706 /*                                                                        */
707 /*    status                                Completion status             */
708 /*                                                                        */
709 /*  CALLS                                                                 */
710 /*                                                                        */
711 /*    _nx_pppoe_server_disable              Actual PPPoE disable function */
712 /*                                                                        */
713 /*  CALLED BY                                                             */
714 /*                                                                        */
715 /*    Application                                                         */
716 /*                                                                        */
717 /*  RELEASE HISTORY                                                       */
718 /*                                                                        */
719 /*    DATE              NAME                      DESCRIPTION             */
720 /*                                                                        */
721 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
722 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
723 /*                                            resulting in version 6.1    */
724 /*                                                                        */
725 /**************************************************************************/
_nxe_pppoe_server_disable(NX_PPPOE_SERVER * pppoe_server_ptr)726 UINT  _nxe_pppoe_server_disable(NX_PPPOE_SERVER *pppoe_server_ptr)
727 {
728 
729 UINT    status;
730 
731     /* Check for invalid input pointers.  */
732     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
733         return(NX_PPPOE_SERVER_PTR_ERROR);
734 
735     /* Call actual PPPoE server instance disable function.  */
736     status =  _nx_pppoe_server_disable(pppoe_server_ptr);
737 
738     /* Return completion status.  */
739     return(status);
740 }
741 
742 
743 /**************************************************************************/
744 /*                                                                        */
745 /*  FUNCTION                                               RELEASE        */
746 /*                                                                        */
747 /*    _nx_pppoe_server_disable                            PORTABLE C      */
748 /*                                                           6.1          */
749 /*  AUTHOR                                                                */
750 /*                                                                        */
751 /*    Yuxin Zhou, Microsoft Corporation                                   */
752 /*                                                                        */
753 /*  DESCRIPTION                                                           */
754 /*                                                                        */
755 /*    This function disables the PPPoE Server feature.                    */
756 /*                                                                        */
757 /*  INPUT                                                                 */
758 /*                                                                        */
759 /*    tx_mutex_get                          Obtain a protection mutex     */
760 /*    tx_mutex_put                          Release protection mutex      */
761 /*    tx_thread_suspend                     Suspend PPPoE helper thread   */
762 /*                                                                        */
763 /*  OUTPUT                                                                */
764 /*                                                                        */
765 /*    status                                Completion status             */
766 /*                                                                        */
767 /*  CALLS                                                                 */
768 /*                                                                        */
769 /*    _nx_pppoe_server_enable               Actual PPPoE enable function  */
770 /*                                                                        */
771 /*  CALLED BY                                                             */
772 /*                                                                        */
773 /*    Application                                                         */
774 /*                                                                        */
775 /*  RELEASE HISTORY                                                       */
776 /*                                                                        */
777 /*    DATE              NAME                      DESCRIPTION             */
778 /*                                                                        */
779 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
780 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
781 /*                                            resulting in version 6.1    */
782 /*                                                                        */
783 /**************************************************************************/
_nx_pppoe_server_disable(NX_PPPOE_SERVER * pppoe_server_ptr)784 UINT  _nx_pppoe_server_disable(NX_PPPOE_SERVER *pppoe_server_ptr)
785 {
786 
787     /* Obtain the IP internal mutex before processing the IP event.  */
788     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
789 
790     /* Set the enabled flag.  */
791     pppoe_server_ptr -> nx_pppoe_enabled = NX_FALSE;
792 
793     /* Suspend the PPPoE server thread.  */
794     tx_thread_suspend(&(pppoe_server_ptr -> nx_pppoe_thread));
795 
796     /* Release the IP internal mutex.  */
797     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
798 
799     /* Return success.  */
800     return(NX_PPPOE_SERVER_SUCCESS);
801 }
802 
803 
804 /**************************************************************************/
805 /*                                                                        */
806 /*  FUNCTION                                               RELEASE        */
807 /*                                                                        */
808 /*    _nxe_pppoe_server_callback_notify_set               PORTABLE C      */
809 /*                                                           6.1          */
810 /*  AUTHOR                                                                */
811 /*                                                                        */
812 /*    Yuxin Zhou, Microsoft Corporation                                   */
813 /*                                                                        */
814 /*  DESCRIPTION                                                           */
815 /*                                                                        */
816 /*    This function checks for errors in the PPPoE Server disable function*/
817 /*    call.                                                               */
818 /*                                                                        */
819 /*  INPUT                                                                 */
820 /*                                                                        */
821 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
822 /*    pppoe_discover_initiation_notify      Routine to call when discovery*/
823 /*                                            initiation data is received */
824 /*    pppoe_discover_request_notify         Routine to call when discovery*/
825 /*                                            reques data is received     */
826 /*    pppoe_discover_terminate_notify       Routine to call when discovery*/
827 /*                                            terminate data is received  */
828 /*    pppoe_discover_terminate_confirm      Routine to call when discovery*/
829 /*                                            terminate data is sent      */
830 /*    pppoe_data_receive_notify             Routine to call when session  */
831 /*                                            data is received            */
832 /*    pppoe_data_send_notify                Routine to call when session  */
833 /*                                            data is sent                */
834 /*                                                                        */
835 /*  OUTPUT                                                                */
836 /*                                                                        */
837 /*    status                                Completion status             */
838 /*                                                                        */
839 /*  CALLS                                                                 */
840 /*                                                                        */
841 /*    _nx_pppoe_server_callback_notify_set  Actual PPPoE callback set     */
842 /*                                            function                    */
843 /*                                                                        */
844 /*  CALLED BY                                                             */
845 /*                                                                        */
846 /*    Application                                                         */
847 /*                                                                        */
848 /*  RELEASE HISTORY                                                       */
849 /*                                                                        */
850 /*    DATE              NAME                      DESCRIPTION             */
851 /*                                                                        */
852 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
853 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
854 /*                                            resulting in version 6.1    */
855 /*                                                                        */
856 /**************************************************************************/
_nxe_pppoe_server_callback_notify_set(NX_PPPOE_SERVER * pppoe_server_ptr,VOID (* pppoe_discover_initiation_notify)(UINT session_index),VOID (* pppoe_discover_request_notify)(UINT session_index,ULONG length,UCHAR * data),VOID (* pppoe_discover_terminate_notify)(UINT session_index),VOID (* pppoe_discover_terminate_confirm)(UINT session_index),VOID (* pppoe_data_receive_notify)(UINT session_index,ULONG length,UCHAR * data,UINT packet_id),VOID (* pppoe_data_send_notify)(UINT session_index,UCHAR * data))857 UINT  _nxe_pppoe_server_callback_notify_set(NX_PPPOE_SERVER *pppoe_server_ptr,
858                                             VOID (* pppoe_discover_initiation_notify)(UINT session_index),
859                                             VOID (* pppoe_discover_request_notify)(UINT session_index, ULONG length, UCHAR *data),
860                                             VOID (* pppoe_discover_terminate_notify)(UINT session_index),
861                                             VOID (* pppoe_discover_terminate_confirm)(UINT session_index),
862                                             VOID (* pppoe_data_receive_notify)(UINT session_index, ULONG length, UCHAR *data, UINT packet_id),
863                                             VOID (* pppoe_data_send_notify)(UINT session_index, UCHAR *data))
864 {
865 
866 UINT    status;
867 
868     /* Check for invalid input pointers.  */
869     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
870         return(NX_PPPOE_SERVER_PTR_ERROR);
871 
872     /* Check to see if pppoe_data_receive_notify is set.  */
873     if (pppoe_data_receive_notify == NX_NULL)
874         return(NX_PPPOE_SERVER_PTR_ERROR);
875 
876     /* Call actual PPPoE service callback notify set function.  */
877     status =  _nx_pppoe_server_callback_notify_set(pppoe_server_ptr, pppoe_discover_initiation_notify, pppoe_discover_request_notify,
878                                                    pppoe_discover_terminate_notify, pppoe_discover_terminate_confirm,
879                                                    pppoe_data_receive_notify, pppoe_data_send_notify);
880 
881     /* Return completion status.  */
882     return(status);
883 }
884 
885 
886 /**************************************************************************/
887 /*                                                                        */
888 /*  FUNCTION                                               RELEASE        */
889 /*                                                                        */
890 /*    _nx_pppoe_server_callback_notify_set                PORTABLE C      */
891 /*                                                           6.1          */
892 /*  AUTHOR                                                                */
893 /*                                                                        */
894 /*    Yuxin Zhou, Microsoft Corporation                                   */
895 /*                                                                        */
896 /*  DESCRIPTION                                                           */
897 /*                                                                        */
898 /*    This function sets the callback notify functions.                   */
899 /*                                                                        */
900 /*  INPUT                                                                 */
901 /*                                                                        */
902 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
903 /*    pppoe_discover_initiation_notify      Routine to call when discovery*/
904 /*                                            initiation data is received */
905 /*    pppoe_discover_request_notify         Routine to call when discovery*/
906 /*                                            reques data is received     */
907 /*    pppoe_discover_terminate_notify       Routine to call when discovery*/
908 /*                                            terminate data is received  */
909 /*    pppoe_discover_terminate_confirm      Routine to call when discovery*/
910 /*                                            terminate data is sent      */
911 /*    pppoe_data_receive_notify             Routine to call when session  */
912 /*                                            data is received            */
913 /*    pppoe_data_send_notify                Routine to call when session  */
914 /*                                            data is sent                */
915 /*                                                                        */
916 /*  OUTPUT                                                                */
917 /*                                                                        */
918 /*    status                                Completion status             */
919 /*                                                                        */
920 /*  CALLS                                                                 */
921 /*                                                                        */
922 /*    tx_mutex_get                          Obtain a protection mutex     */
923 /*    tx_mutex_put                          Release protection mutex      */
924 /*                                                                        */
925 /*  CALLED BY                                                             */
926 /*                                                                        */
927 /*    Application                                                         */
928 /*                                                                        */
929 /*  RELEASE HISTORY                                                       */
930 /*                                                                        */
931 /*    DATE              NAME                      DESCRIPTION             */
932 /*                                                                        */
933 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
934 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
935 /*                                            resulting in version 6.1    */
936 /*                                                                        */
937 /**************************************************************************/
_nx_pppoe_server_callback_notify_set(NX_PPPOE_SERVER * pppoe_server_ptr,VOID (* pppoe_discover_initiation_notify)(UINT session_index),VOID (* pppoe_discover_request_notify)(UINT session_index,ULONG length,UCHAR * data),VOID (* pppoe_discover_terminate_notify)(UINT session_index),VOID (* pppoe_discover_terminate_confirm)(UINT session_index),VOID (* pppoe_data_receive_notify)(UINT session_index,ULONG length,UCHAR * data,UINT packet_id),VOID (* pppoe_data_send_notify)(UINT session_index,UCHAR * data))938 UINT  _nx_pppoe_server_callback_notify_set(NX_PPPOE_SERVER *pppoe_server_ptr,
939                                            VOID (* pppoe_discover_initiation_notify)(UINT session_index),
940                                            VOID (* pppoe_discover_request_notify)(UINT session_index, ULONG length, UCHAR *data),
941                                            VOID (* pppoe_discover_terminate_notify)(UINT session_index),
942                                            VOID (* pppoe_discover_terminate_confirm)(UINT session_index),
943                                            VOID (* pppoe_data_receive_notify)(UINT session_index, ULONG length, UCHAR *data, UINT packet_id),
944                                            VOID (* pppoe_data_send_notify)(UINT session_index, UCHAR *data))
945 {
946 
947     /* Obtain the IP internal mutex before processing the IP event.  */
948     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
949 
950     /* Install PPPoE notify function pointer */
951     pppoe_server_ptr -> nx_pppoe_discover_initiation_notify = pppoe_discover_initiation_notify;
952     pppoe_server_ptr -> nx_pppoe_discover_request_notify = pppoe_discover_request_notify;
953     pppoe_server_ptr -> nx_pppoe_discover_terminate_notify = pppoe_discover_terminate_notify;
954     pppoe_server_ptr -> nx_pppoe_discover_terminate_confirm = pppoe_discover_terminate_confirm;
955     pppoe_server_ptr -> nx_pppoe_data_receive_notify = pppoe_data_receive_notify;
956     pppoe_server_ptr -> nx_pppoe_data_send_notify = pppoe_data_send_notify;
957 
958     /* Release the IP internal mutex.  */
959     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
960 
961     /* Return success.  */
962     return(NX_PPPOE_SERVER_SUCCESS);
963 }
964 
965 
966 /**************************************************************************/
967 /*                                                                        */
968 /*  FUNCTION                                               RELEASE        */
969 /*                                                                        */
970 /*    _nxe_pppoe_server_service_name_set                  PORTABLE C      */
971 /*                                                           6.1          */
972 /*  AUTHOR                                                                */
973 /*                                                                        */
974 /*    Yuxin Zhou, Microsoft Corporation                                   */
975 /*                                                                        */
976 /*  DESCRIPTION                                                           */
977 /*                                                                        */
978 /*    This function checks for errors in the PPPoE service name set       */
979 /*    function call.                                                      */
980 /*                                                                        */
981 /*  INPUT                                                                 */
982 /*                                                                        */
983 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
984 /*    service_name                          Pointer to an array service   */
985 /*                                            names.  Each service name   */
986 /*                                            must be Null-terminated     */
987 /*                                            string.                     */
988 /*    service_name_count                    The counter of service names  */
989 /*                                                                        */
990 /*  OUTPUT                                                                */
991 /*                                                                        */
992 /*    status                                Completion status             */
993 /*                                                                        */
994 /*  CALLS                                                                 */
995 /*                                                                        */
996 /*    _nx_pppoe_server_service_name_set     Actual PPPoE service name set */
997 /*                                            function                    */
998 /*                                                                        */
999 /*  CALLED BY                                                             */
1000 /*                                                                        */
1001 /*    Application                                                         */
1002 /*                                                                        */
1003 /*  RELEASE HISTORY                                                       */
1004 /*                                                                        */
1005 /*    DATE              NAME                      DESCRIPTION             */
1006 /*                                                                        */
1007 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1008 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1009 /*                                            resulting in version 6.1    */
1010 /*                                                                        */
1011 /**************************************************************************/
_nxe_pppoe_server_service_name_set(NX_PPPOE_SERVER * pppoe_server_ptr,UCHAR ** service_name,UINT service_name_count)1012 UINT  _nxe_pppoe_server_service_name_set(NX_PPPOE_SERVER *pppoe_server_ptr, UCHAR **service_name, UINT service_name_count)
1013 {
1014 
1015 UINT    status;
1016 
1017     /* Check for invalid input pointers.  */
1018     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
1019         return(NX_PPPOE_SERVER_PTR_ERROR);
1020 
1021     /* Call actual PPPoE service name set function.  */
1022     status =  _nx_pppoe_server_service_name_set(pppoe_server_ptr, service_name, service_name_count);
1023 
1024     /* Return completion status.  */
1025     return(status);
1026 }
1027 
1028 
1029 /**************************************************************************/
1030 /*                                                                        */
1031 /*  FUNCTION                                               RELEASE        */
1032 /*                                                                        */
1033 /*    _nx_pppoe_server_service_name_set                   PORTABLE C      */
1034 /*                                                           6.1          */
1035 /*  AUTHOR                                                                */
1036 /*                                                                        */
1037 /*    Yuxin Zhou, Microsoft Corporation                                   */
1038 /*                                                                        */
1039 /*  DESCRIPTION                                                           */
1040 /*                                                                        */
1041 /*    This function sets the the PPPoE service name.                      */
1042 /*                                                                        */
1043 /*  INPUT                                                                 */
1044 /*                                                                        */
1045 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1046 /*    service_name                          Pointer to an array service   */
1047 /*                                            names.  Each service name   */
1048 /*                                            must be Null-terminated     */
1049 /*                                            string.                     */
1050 /*    service_name_count                    The counter of service names  */
1051 /*                                                                        */
1052 /*  OUTPUT                                                                */
1053 /*                                                                        */
1054 /*    status                                Completion status             */
1055 /*                                                                        */
1056 /*  CALLS                                                                 */
1057 /*                                                                        */
1058 /*    tx_mutex_get                          Obtain a protection mutex     */
1059 /*    tx_mutex_put                          Release protection mutex      */
1060 /*                                                                        */
1061 /*  CALLED BY                                                             */
1062 /*                                                                        */
1063 /*    Application                                                         */
1064 /*                                                                        */
1065 /*  RELEASE HISTORY                                                       */
1066 /*                                                                        */
1067 /*    DATE              NAME                      DESCRIPTION             */
1068 /*                                                                        */
1069 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1070 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1071 /*                                            resulting in version 6.1    */
1072 /*                                                                        */
1073 /**************************************************************************/
_nx_pppoe_server_service_name_set(NX_PPPOE_SERVER * pppoe_server_ptr,UCHAR ** service_name,UINT service_name_count)1074 UINT  _nx_pppoe_server_service_name_set(NX_PPPOE_SERVER *pppoe_server_ptr, UCHAR **service_name, UINT service_name_count)
1075 {
1076 
1077     /* Obtain the IP internal mutex before processing the IP event.  */
1078     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1079 
1080     /* Setup service name pointer.  */
1081     pppoe_server_ptr -> nx_pppoe_service_name = service_name;
1082 
1083     /* Setup service name count.  */
1084     pppoe_server_ptr -> nx_pppoe_service_name_count = service_name_count;
1085 
1086     /* Release the IP internal mutex.  */
1087     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1088 
1089     /* Return success.  */
1090     return(NX_PPPOE_SERVER_SUCCESS);
1091 
1092 }
1093 
1094 
1095 /**************************************************************************/
1096 /*                                                                        */
1097 /*  FUNCTION                                               RELEASE        */
1098 /*                                                                        */
1099 /*    _nxe_pppoe_server_session_send                      PORTABLE C      */
1100 /*                                                           6.1          */
1101 /*  AUTHOR                                                                */
1102 /*                                                                        */
1103 /*    Yuxin Zhou, Microsoft Corporation                                   */
1104 /*                                                                        */
1105 /*  DESCRIPTION                                                           */
1106 /*                                                                        */
1107 /*    This function checks for errors in the PPPoE session data send      */
1108 /*    function call.                                                      */
1109 /*                                                                        */
1110 /*  INPUT                                                                 */
1111 /*                                                                        */
1112 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1113 /*    session_index                         Session index                 */
1114 /*    data_ptr                              Session Data pointer          */
1115 /*    data_length                           Length of Session Data        */
1116 /*                                                                        */
1117 /*  OUTPUT                                                                */
1118 /*                                                                        */
1119 /*    status                                Completion status             */
1120 /*                                                                        */
1121 /*  CALLS                                                                 */
1122 /*                                                                        */
1123 /*    _nx_pppoe_server_session_send         Actual PPPoE Session data send*/
1124 /*                                            function                    */
1125 /*                                                                        */
1126 /*  CALLED BY                                                             */
1127 /*                                                                        */
1128 /*    Application                                                         */
1129 /*                                                                        */
1130 /*  RELEASE HISTORY                                                       */
1131 /*                                                                        */
1132 /*    DATE              NAME                      DESCRIPTION             */
1133 /*                                                                        */
1134 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1135 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1136 /*                                            resulting in version 6.1    */
1137 /*                                                                        */
1138 /**************************************************************************/
_nxe_pppoe_server_session_send(NX_PPPOE_SERVER * pppoe_server_ptr,UINT session_index,UCHAR * data_ptr,UINT data_length)1139 UINT  _nxe_pppoe_server_session_send(NX_PPPOE_SERVER *pppoe_server_ptr, UINT session_index, UCHAR *data_ptr, UINT data_length)
1140 {
1141 
1142 UINT    status;
1143 
1144     /* Check for invalid input pointers.  */
1145     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID) || (data_ptr == NX_NULL))
1146         return(NX_PPPOE_SERVER_PTR_ERROR);
1147 
1148     /* Check the service_name_count.  */
1149     if (data_length == 0)
1150         return(NX_PPPOE_SERVER_PTR_ERROR);
1151 
1152     /* Check to see if PPPoE is enabled.  */
1153     if (pppoe_server_ptr -> nx_pppoe_enabled != NX_TRUE)
1154         return(NX_PPPOE_SERVER_NOT_ENABLED);
1155 
1156     /* Check for invalid session index.  */
1157     if(session_index >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
1158         return(NX_PPPOE_SERVER_INVALID_SESSION);
1159 
1160     /* Check to see if PPPoE session is established.  */
1161     if ((pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_valid != NX_TRUE) ||
1162         (pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_session_id == 0))
1163         return(NX_PPPOE_SERVER_SESSION_NOT_ESTABLISHED);
1164 
1165     /* Call actual PPPoE session send function.  */
1166     status =  _nx_pppoe_server_session_send(pppoe_server_ptr, session_index, data_ptr, data_length);
1167 
1168     /* Return completion status.  */
1169     return(status);
1170 }
1171 
1172 
1173 /**************************************************************************/
1174 /*                                                                        */
1175 /*  FUNCTION                                               RELEASE        */
1176 /*                                                                        */
1177 /*    _nx_pppoe_server_session_send                       PORTABLE C      */
1178 /*                                                           6.1          */
1179 /*  AUTHOR                                                                */
1180 /*                                                                        */
1181 /*    Yuxin Zhou, Microsoft Corporation                                   */
1182 /*                                                                        */
1183 /*  DESCRIPTION                                                           */
1184 /*                                                                        */
1185 /*    This function builds an PPPoE Session packet and calls the          */
1186 /*    associated driver to send it out on the network.                    */
1187 /*                                                                        */
1188 /*  INPUT                                                                 */
1189 /*                                                                        */
1190 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1191 /*    session_index                         Session index                 */
1192 /*    data_ptr                              Session Data pointer          */
1193 /*    data_length                           Length of Session Data        */
1194 /*                                                                        */
1195 /*  OUTPUT                                                                */
1196 /*                                                                        */
1197 /*    status                                Completion status             */
1198 /*                                                                        */
1199 /*  CALLS                                                                 */
1200 /*                                                                        */
1201 /*    tx_mutex_get                          Obtain a protection mutex     */
1202 /*    tx_mutex_put                          Release protection mutex      */
1203 /*    nx_packet_allocate                    Allocate a packet for the     */
1204 /*                                            PPPoE Session               */
1205 /*    nx_packet_release                     Release packet to packet pool */
1206 /*    nx_packet_data_append                 Copies the specified data     */
1207 /*    _nx_pppoe_server_data_add             Add PPPoE data                */
1208 /*    _nx_pppoe_server_packet_send          Send out PPPoE packet         */
1209 /*                                                                        */
1210 /*  CALLED BY                                                             */
1211 /*                                                                        */
1212 /*    Application                                                         */
1213 /*                                                                        */
1214 /*  RELEASE HISTORY                                                       */
1215 /*                                                                        */
1216 /*    DATE              NAME                      DESCRIPTION             */
1217 /*                                                                        */
1218 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1219 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1220 /*                                            resulting in version 6.1    */
1221 /*                                                                        */
1222 /**************************************************************************/
_nx_pppoe_server_session_send(NX_PPPOE_SERVER * pppoe_server_ptr,UINT session_index,UCHAR * data_ptr,UINT data_length)1223 UINT  _nx_pppoe_server_session_send(NX_PPPOE_SERVER *pppoe_server_ptr, UINT session_index, UCHAR *data_ptr, UINT data_length)
1224 {
1225 
1226 NX_PPPOE_CLIENT_SESSION    *client_session_ptr;
1227 NX_PACKET                  *packet_ptr;
1228 UCHAR                      *work_ptr;
1229 UINT                        status;
1230 
1231 
1232     /* Allocate a PPPoE packet.  */
1233     status =  nx_packet_allocate(pppoe_server_ptr -> nx_pppoe_packet_pool_ptr, &packet_ptr, NX_PHYSICAL_HEADER, NX_PPPOE_SERVER_PACKET_TIMEOUT);
1234 
1235     /* Was the packet allocation successful?  */
1236     if (status != NX_SUCCESS)
1237     {
1238 
1239         /* Return status.  */
1240         return(status);
1241     }
1242 
1243     /* Obtain the IP internal mutex.  */
1244     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1245 
1246     /* Set the client session pointer.  */
1247     client_session_ptr = &(pppoe_server_ptr -> nx_pppoe_client_session[session_index]);
1248 
1249     /* Set the work pointer.  */
1250     work_ptr = packet_ptr -> nx_packet_prepend_ptr;
1251 
1252     /* Added the PPPoE header.  */
1253     /*
1254      *  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
1255      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1256      * |  VER | TYPE  |      CODE       |         SESSION_ID           |
1257      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1258      * |           LENGTH               |          payload
1259      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1260     */
1261 
1262     /* Add version and type.  */
1263     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_VER_TYPE, 1, NX_PPPOE_SERVER_VERSION_TYPE);
1264 
1265     /* Add code.  */
1266     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_CODE, 1, NX_PPPOE_SERVER_CODE_ZERO);
1267 
1268     /* Add session id.  */
1269     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_SESSION_ID, 2, client_session_ptr -> nx_pppoe_session_id);
1270 
1271     /* Add length.  */
1272     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_LENGTH, 2, data_length);
1273 
1274     /* Update the pointer to add the payload of PPPoE.  */
1275     packet_ptr -> nx_packet_append_ptr += NX_PPPOE_SERVER_OFFSET_PAYLOAD;
1276     packet_ptr -> nx_packet_length += NX_PPPOE_SERVER_OFFSET_PAYLOAD;
1277 
1278     /* Release the mutex before a blocking call. */
1279     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1280 
1281     /* Append the data into PPPoE packet.  */
1282     status = nx_packet_data_append(packet_ptr, data_ptr, data_length, pppoe_server_ptr -> nx_pppoe_packet_pool_ptr, NX_PPPOE_SERVER_PACKET_TIMEOUT);
1283 
1284     /* Was the packet allocation successful?  */
1285     if (status != NX_SUCCESS)
1286     {
1287 
1288         /* Relase the packet.  */
1289         nx_packet_release(packet_ptr);
1290 
1291         /* Return status.  */
1292         return(status);
1293     }
1294 
1295     /* Regain obtain the IP internal mutex. */
1296     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1297 
1298     /* Send PPPoE session packet.  */
1299     _nx_pppoe_server_packet_send(pppoe_server_ptr, client_session_ptr, packet_ptr, NX_LINK_PPPOE_SESSION_SEND);
1300 
1301     /* Check the PPPoE send function.  */
1302     if (pppoe_server_ptr -> nx_pppoe_data_send_notify)
1303     {
1304 
1305         /* Call the function to send the data frame.  */
1306         pppoe_server_ptr -> nx_pppoe_data_send_notify(session_index, data_ptr);
1307     }
1308 
1309     /* Release the IP internal mutex.  */
1310     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1311 
1312     /* Return success.  */
1313     return(NX_PPPOE_SERVER_SUCCESS);
1314 }
1315 
1316 
1317 /**************************************************************************/
1318 /*                                                                        */
1319 /*  FUNCTION                                               RELEASE        */
1320 /*                                                                        */
1321 /*    _nxe_pppoe_server_session_packet_send               PORTABLE C      */
1322 /*                                                           6.1          */
1323 /*  AUTHOR                                                                */
1324 /*                                                                        */
1325 /*    Yuxin Zhou, Microsoft Corporation                                   */
1326 /*                                                                        */
1327 /*  DESCRIPTION                                                           */
1328 /*                                                                        */
1329 /*    This function checks for errors in the PPPoE session packet send    */
1330 /*    function call.                                                      */
1331 /*                                                                        */
1332 /*  INPUT                                                                 */
1333 /*                                                                        */
1334 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1335 /*    session_index                         Session index                 */
1336 /*    packet_ptr                            Pointer to packet to send     */
1337 /*                                                                        */
1338 /*  OUTPUT                                                                */
1339 /*                                                                        */
1340 /*    status                                Completion status             */
1341 /*                                                                        */
1342 /*  CALLS                                                                 */
1343 /*                                                                        */
1344 /*    _nx_pppoe_server_session_packet_send  Actual PPPoE Session data send*/
1345 /*                                            function                    */
1346 /*                                                                        */
1347 /*  CALLED BY                                                             */
1348 /*                                                                        */
1349 /*    Application                                                         */
1350 /*                                                                        */
1351 /*  RELEASE HISTORY                                                       */
1352 /*                                                                        */
1353 /*    DATE              NAME                      DESCRIPTION             */
1354 /*                                                                        */
1355 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1356 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1357 /*                                            resulting in version 6.1    */
1358 /*                                                                        */
1359 /**************************************************************************/
_nxe_pppoe_server_session_packet_send(NX_PPPOE_SERVER * pppoe_server_ptr,UINT session_index,NX_PACKET * packet_ptr)1360 UINT  _nxe_pppoe_server_session_packet_send(NX_PPPOE_SERVER *pppoe_server_ptr, UINT session_index, NX_PACKET *packet_ptr)
1361 {
1362 
1363 UINT    status;
1364 
1365     /* Check for invalid packet.  */
1366     if (packet_ptr == NX_NULL)
1367     {
1368         return(NX_PPPOE_SERVER_PTR_ERROR);
1369     }
1370 
1371     /* Check for minimum packet length (PPP DATA Header).  */
1372     if (packet_ptr -> nx_packet_length < 2)
1373     {
1374 
1375         /* Release the packet.  */
1376         nx_packet_transmit_release(packet_ptr);
1377 
1378         return(NX_PPPOE_SERVER_PACKET_PAYLOAD_ERROR);
1379     }
1380 
1381     /* Check for invalid input pointers.  */
1382     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
1383     {
1384 
1385         /* Adjust the packet prepend to remove the PPP header.  */
1386         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
1387         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
1388 
1389         /* Release the packet.  */
1390         nx_packet_transmit_release(packet_ptr);
1391 
1392         return(NX_PPPOE_SERVER_PTR_ERROR);
1393     }
1394 
1395     /* Check to see if PPPoE is enabled.  */
1396     if (pppoe_server_ptr -> nx_pppoe_enabled != NX_TRUE)
1397     {
1398 
1399         /* Adjust the packet prepend to remove the PPP header.  */
1400         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
1401         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
1402 
1403         /* Release the packet.  */
1404         nx_packet_transmit_release(packet_ptr);
1405 
1406         return(NX_PPPOE_SERVER_NOT_ENABLED);
1407     }
1408 
1409     /* Check for invalid session index.  */
1410     if(session_index >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
1411     {
1412 
1413         /* Adjust the packet prepend to remove the PPP header.  */
1414         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
1415         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
1416 
1417         /* Release the packet.  */
1418         nx_packet_transmit_release(packet_ptr);
1419 
1420         return(NX_PPPOE_SERVER_INVALID_SESSION);
1421     }
1422 
1423     /* Check to see if PPPoE session is established.  */
1424     if ((pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_valid != NX_TRUE) ||
1425         (pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_session_id == 0))
1426     {
1427 
1428         /* Adjust the packet prepend to remove the PPP header.  */
1429         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
1430         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
1431 
1432         /* Release the packet.  */
1433         nx_packet_transmit_release(packet_ptr);
1434 
1435         return(NX_PPPOE_SERVER_SESSION_NOT_ESTABLISHED);
1436     }
1437 
1438     /* Call actual PPPoE session packet_send function.  */
1439     status =  _nx_pppoe_server_session_packet_send(pppoe_server_ptr, session_index, packet_ptr);
1440 
1441     /* Return completion status.  */
1442     return(status);
1443 }
1444 
1445 
1446 /**************************************************************************/
1447 /*                                                                        */
1448 /*  FUNCTION                                               RELEASE        */
1449 /*                                                                        */
1450 /*    _nx_pppoe_server_session_packet_send                PORTABLE C      */
1451 /*                                                           6.1          */
1452 /*  AUTHOR                                                                */
1453 /*                                                                        */
1454 /*    Yuxin Zhou, Microsoft Corporation                                   */
1455 /*                                                                        */
1456 /*  DESCRIPTION                                                           */
1457 /*                                                                        */
1458 /*    This function builds an PPPoE Session packet and calls the          */
1459 /*    associated driver to send it out on the network.                    */
1460 /*                                                                        */
1461 /*  INPUT                                                                 */
1462 /*                                                                        */
1463 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1464 /*    session_index                         Session index                 */
1465 /*    data_ptr                              Session Data pointer          */
1466 /*    data_length                           Length of Session Data        */
1467 /*                                                                        */
1468 /*  OUTPUT                                                                */
1469 /*                                                                        */
1470 /*    status                                Completion status             */
1471 /*                                                                        */
1472 /*  CALLS                                                                 */
1473 /*                                                                        */
1474 /*    tx_mutex_get                          Obtain a protection mutex     */
1475 /*    tx_mutex_put                          Release protection mutex      */
1476 /*    nx_packet_release                     Release packet to packet pool */
1477 /*    nx_packet_data_append                 Copies the specified data     */
1478 /*    _nx_pppoe_server_data_add             Add PPPoE data                */
1479 /*    _nx_pppoe_server_packet_send          Send out PPPoE packet         */
1480 /*                                                                        */
1481 /*  CALLED BY                                                             */
1482 /*                                                                        */
1483 /*    Application                                                         */
1484 /*                                                                        */
1485 /*  RELEASE HISTORY                                                       */
1486 /*                                                                        */
1487 /*    DATE              NAME                      DESCRIPTION             */
1488 /*                                                                        */
1489 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1490 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1491 /*                                            resulting in version 6.1    */
1492 /*                                                                        */
1493 /**************************************************************************/
_nx_pppoe_server_session_packet_send(NX_PPPOE_SERVER * pppoe_server_ptr,UINT session_index,NX_PACKET * packet_ptr)1494 UINT  _nx_pppoe_server_session_packet_send(NX_PPPOE_SERVER *pppoe_server_ptr, UINT session_index, NX_PACKET *packet_ptr)
1495 {
1496 
1497 NX_PPPOE_CLIENT_SESSION    *client_session_ptr;
1498 UCHAR                      *work_ptr;
1499 
1500 
1501     /* Obtain the IP internal mutex.  */
1502     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1503 
1504     /* Check for an invalid packet prepend pointer.  */
1505     if ((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) < NX_PPPOE_SERVER_OFFSET_PAYLOAD)
1506     {
1507 
1508         /* Adjust the packet prepend to remove the PPP header.  */
1509         packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr + 2;
1510         packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - 2;
1511 
1512         /* Release the packet.  */
1513         nx_packet_transmit_release(packet_ptr);
1514 
1515         /* Release the IP internal mutex.  */
1516         tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1517 
1518         /* Return error code.  */
1519         return(NX_PPPOE_SERVER_PACKET_PAYLOAD_ERROR);
1520     }
1521 
1522     /* Set the client session pointer.  */
1523     client_session_ptr = &(pppoe_server_ptr -> nx_pppoe_client_session[session_index]);
1524 
1525     /* Set the work pointer.  */
1526     packet_ptr -> nx_packet_prepend_ptr -= NX_PPPOE_SERVER_OFFSET_PAYLOAD;
1527     work_ptr = packet_ptr -> nx_packet_prepend_ptr;
1528 
1529     /* Added the PPPoE header.  */
1530     /*
1531      *  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
1532      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1533      * |  VER | TYPE  |      CODE       |         SESSION_ID           |
1534      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1535      * |           LENGTH               |          payload
1536      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1537     */
1538 
1539     /* Add version and type.  */
1540     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_VER_TYPE, 1, NX_PPPOE_SERVER_VERSION_TYPE);
1541 
1542     /* Add code.  */
1543     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_CODE, 1, NX_PPPOE_SERVER_CODE_ZERO);
1544 
1545     /* Add session id.  */
1546     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_SESSION_ID, 2, client_session_ptr -> nx_pppoe_session_id);
1547 
1548     /* Add length.  */
1549     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_LENGTH, 2, packet_ptr -> nx_packet_length);
1550 
1551     /* Update the packet length.  */
1552     packet_ptr -> nx_packet_length += NX_PPPOE_SERVER_OFFSET_PAYLOAD;
1553 
1554     /* Send PPPoE session packet.  */
1555     _nx_pppoe_server_packet_send(pppoe_server_ptr, client_session_ptr, packet_ptr, NX_LINK_PPPOE_SESSION_SEND);
1556 
1557     /* Release the IP internal mutex.  */
1558     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1559 
1560     /* Return success.  */
1561     return(NX_PPPOE_SERVER_SUCCESS);
1562 }
1563 
1564 
1565 /**************************************************************************/
1566 /*                                                                        */
1567 /*  FUNCTION                                               RELEASE        */
1568 /*                                                                        */
1569 /*    _nxe_pppoe_server_session_terminate                 PORTABLE C      */
1570 /*                                                           6.1          */
1571 /*  AUTHOR                                                                */
1572 /*                                                                        */
1573 /*    Yuxin Zhou, Microsoft Corporation                                   */
1574 /*                                                                        */
1575 /*  DESCRIPTION                                                           */
1576 /*                                                                        */
1577 /*    This function checks for errors in the PPPoE session terminate      */
1578 /*    function call.                                                      */
1579 /*                                                                        */
1580 /*  INPUT                                                                 */
1581 /*                                                                        */
1582 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1583 /*    session_index                         Session index                 */
1584 /*                                                                        */
1585 /*  OUTPUT                                                                */
1586 /*                                                                        */
1587 /*    status                                Completion status             */
1588 /*                                                                        */
1589 /*  CALLS                                                                 */
1590 /*                                                                        */
1591 /*    _nx_pppoe_server_session_terminate    Actual PPPoE Session terminate*/
1592 /*                                            function                    */
1593 /*                                                                        */
1594 /*  CALLED BY                                                             */
1595 /*                                                                        */
1596 /*    Application                                                         */
1597 /*                                                                        */
1598 /*  RELEASE HISTORY                                                       */
1599 /*                                                                        */
1600 /*    DATE              NAME                      DESCRIPTION             */
1601 /*                                                                        */
1602 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1603 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1604 /*                                            resulting in version 6.1    */
1605 /*                                                                        */
1606 /**************************************************************************/
_nxe_pppoe_server_session_terminate(NX_PPPOE_SERVER * pppoe_server_ptr,UINT session_index)1607 UINT  _nxe_pppoe_server_session_terminate(NX_PPPOE_SERVER *pppoe_server_ptr, UINT session_index)
1608 {
1609 
1610 UINT    status;
1611 
1612     /* Check for invalid input pointers.  */
1613     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
1614         return(NX_PPPOE_SERVER_PTR_ERROR);
1615 
1616     /* Check to see if PPPoE is enabled.  */
1617     if (pppoe_server_ptr -> nx_pppoe_enabled != NX_TRUE)
1618         return(NX_PPPOE_SERVER_NOT_ENABLED);
1619 
1620     /* Check for invalid session index.  */
1621     if(session_index >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
1622         return(NX_PPPOE_SERVER_INVALID_SESSION);
1623 
1624     /* Check to see if PPPoE session is established.  */
1625     if ((pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_valid != NX_TRUE) ||
1626         (pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_session_id == 0))
1627         return(NX_PPPOE_SERVER_SESSION_NOT_ESTABLISHED);
1628 
1629     /* Call actual PPPoE session terminate function.  */
1630     status =  _nx_pppoe_server_session_terminate(pppoe_server_ptr, session_index);
1631 
1632     /* Return completion status.  */
1633     return(status);
1634 }
1635 
1636 
1637 /**************************************************************************/
1638 /*                                                                        */
1639 /*  FUNCTION                                               RELEASE        */
1640 /*                                                                        */
1641 /*    _nx_pppoe_server_session_terminate                  PORTABLE C      */
1642 /*                                                           6.1          */
1643 /*  AUTHOR                                                                */
1644 /*                                                                        */
1645 /*    Yuxin Zhou, Microsoft Corporation                                   */
1646 /*                                                                        */
1647 /*  DESCRIPTION                                                           */
1648 /*                                                                        */
1649 /*    This function builds an PPPoE packet to terminate the session.      */
1650 /*                                                                        */
1651 /*  INPUT                                                                 */
1652 /*                                                                        */
1653 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1654 /*    session_index                         Session index                 */
1655 /*                                                                        */
1656 /*  OUTPUT                                                                */
1657 /*                                                                        */
1658 /*    status                                Completion status             */
1659 /*                                                                        */
1660 /*  CALLS                                                                 */
1661 /*                                                                        */
1662 /*    tx_mutex_get                          Obtain a protection mutex     */
1663 /*    tx_mutex_put                          Release protection mutex      */
1664 /*    _nx_pppoe_server_discovery_send       Send out PPPoE packet         */
1665 /*    _nx_pppoe_server_session_cleanup      Cleanup PPPoE session         */
1666 /*                                                                        */
1667 /*  CALLED BY                                                             */
1668 /*                                                                        */
1669 /*    Application                                                         */
1670 /*                                                                        */
1671 /*  RELEASE HISTORY                                                       */
1672 /*                                                                        */
1673 /*    DATE              NAME                      DESCRIPTION             */
1674 /*                                                                        */
1675 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1676 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1677 /*                                            resulting in version 6.1    */
1678 /*                                                                        */
1679 /**************************************************************************/
_nx_pppoe_server_session_terminate(NX_PPPOE_SERVER * pppoe_server_ptr,UINT session_index)1680 UINT  _nx_pppoe_server_session_terminate(NX_PPPOE_SERVER *pppoe_server_ptr, UINT session_index)
1681 {
1682 
1683 NX_PPPOE_CLIENT_SESSION    *client_session_ptr;
1684 UINT                        status;
1685 
1686     /* Obtain the IP internal mutex before processing the IP event.  */
1687     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1688 
1689     /* Set the client session pointer.  */
1690     client_session_ptr = &(pppoe_server_ptr -> nx_pppoe_client_session[session_index]);
1691 
1692     /* Terminate the PPPoE session.  */
1693     status = _nx_pppoe_server_discovery_send(pppoe_server_ptr, client_session_ptr, NX_PPPOE_SERVER_CODE_PADT);
1694 
1695     /* Check the status.  */
1696     if (status == NX_PPPOE_SERVER_SUCCESS)
1697     {
1698 
1699         /* Cleanup the session.  */
1700         _nx_pppoe_server_session_cleanup(client_session_ptr);
1701 
1702         /* Check the PPPoE terminate confirm function.  */
1703         if (pppoe_server_ptr -> nx_pppoe_discover_terminate_confirm)
1704         {
1705 
1706             /* Call terminate confirm function.  */
1707             pppoe_server_ptr -> nx_pppoe_discover_terminate_confirm(session_index);
1708         }
1709     }
1710 
1711     /* Release the IP internal mutex.  */
1712     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1713 
1714     /* Return status.  */
1715     return(status);
1716 }
1717 
1718 
1719 /**************************************************************************/
1720 /*                                                                        */
1721 /*  FUNCTION                                               RELEASE        */
1722 /*                                                                        */
1723 /*    _nxe_pppoe_server_session_get                       PORTABLE C      */
1724 /*                                                           6.1          */
1725 /*  AUTHOR                                                                */
1726 /*                                                                        */
1727 /*    Yuxin Zhou, Microsoft Corporation                                   */
1728 /*                                                                        */
1729 /*  DESCRIPTION                                                           */
1730 /*                                                                        */
1731 /*    This function checks for errors in the PPPoE session get function   */
1732 /*    call.                                                               */
1733 /*                                                                        */
1734 /*  INPUT                                                                 */
1735 /*                                                                        */
1736 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1737 /*    session_index                         The index of Client Session   */
1738 /*    client_mac_msw                        Client physical address MSW   */
1739 /*    client_mac_lsw                        Client physical address LSW   */
1740 /*    session_id                            Session ID                    */
1741 /*                                                                        */
1742 /*  OUTPUT                                                                */
1743 /*                                                                        */
1744 /*    status                                Completion status             */
1745 /*                                                                        */
1746 /*  CALLS                                                                 */
1747 /*                                                                        */
1748 /*    _nx_pppoe_server_session_get          Actual PPPoE Session get      */
1749 /*                                            function                    */
1750 /*                                                                        */
1751 /*  CALLED BY                                                             */
1752 /*                                                                        */
1753 /*    Application                                                         */
1754 /*                                                                        */
1755 /*  RELEASE HISTORY                                                       */
1756 /*                                                                        */
1757 /*    DATE              NAME                      DESCRIPTION             */
1758 /*                                                                        */
1759 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1760 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1761 /*                                            resulting in version 6.1    */
1762 /*                                                                        */
1763 /**************************************************************************/
_nxe_pppoe_server_session_get(NX_PPPOE_SERVER * pppoe_server_ptr,UINT session_index,ULONG * client_mac_msw,ULONG * client_mac_lsw,ULONG * session_id)1764 UINT  _nxe_pppoe_server_session_get(NX_PPPOE_SERVER *pppoe_server_ptr, UINT session_index, ULONG *client_mac_msw, ULONG *client_mac_lsw, ULONG *session_id)
1765 {
1766 
1767 UINT    status;
1768 
1769     /* Check for invalid input pointers.  */
1770     if ((pppoe_server_ptr == NX_NULL) || (pppoe_server_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
1771         return(NX_PPPOE_SERVER_PTR_ERROR);
1772 
1773     /* Check for invalid session index.  */
1774     if(session_index >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
1775         return(NX_PPPOE_SERVER_INVALID_SESSION);
1776 
1777     /* Call actual PPPoE session get function.  */
1778     status =  _nx_pppoe_server_session_get(pppoe_server_ptr, session_index, client_mac_msw, client_mac_lsw, session_id);
1779 
1780     /* Return completion status.  */
1781     return(status);
1782 }
1783 
1784 
1785 /**************************************************************************/
1786 /*                                                                        */
1787 /*  FUNCTION                                               RELEASE        */
1788 /*                                                                        */
1789 /*    _nx_pppoe_server_session_get                        PORTABLE C      */
1790 /*                                                           6.1          */
1791 /*  AUTHOR                                                                */
1792 /*                                                                        */
1793 /*    Yuxin Zhou, Microsoft Corporation                                   */
1794 /*                                                                        */
1795 /*  DESCRIPTION                                                           */
1796 /*                                                                        */
1797 /*    This function builds an PPPoE packet to get the session physical    */
1798 /*    address and session id.                                             */
1799 /*                                                                        */
1800 /*  INPUT                                                                 */
1801 /*                                                                        */
1802 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
1803 /*    session_index                         The index of Client Session   */
1804 /*    client_mac_msw                        Client physical address MSW   */
1805 /*    client_mac_lsw                        Client physical address LSW   */
1806 /*    session_id                            Session ID                    */
1807 /*                                                                        */
1808 /*  OUTPUT                                                                */
1809 /*                                                                        */
1810 /*    status                                Completion status             */
1811 /*                                                                        */
1812 /*  CALLS                                                                 */
1813 /*                                                                        */
1814 /*    tx_mutex_get                          Obtain a protection mutex     */
1815 /*    tx_mutex_put                          Release protection mutex      */
1816 /*                                                                        */
1817 /*  CALLED BY                                                             */
1818 /*                                                                        */
1819 /*    Application                                                         */
1820 /*                                                                        */
1821 /*  RELEASE HISTORY                                                       */
1822 /*                                                                        */
1823 /*    DATE              NAME                      DESCRIPTION             */
1824 /*                                                                        */
1825 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1826 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1827 /*                                            resulting in version 6.1    */
1828 /*                                                                        */
1829 /**************************************************************************/
_nx_pppoe_server_session_get(NX_PPPOE_SERVER * pppoe_server_ptr,UINT session_index,ULONG * client_mac_msw,ULONG * client_mac_lsw,ULONG * session_id)1830 UINT  _nx_pppoe_server_session_get(NX_PPPOE_SERVER *pppoe_server_ptr, UINT session_index, ULONG *client_mac_msw, ULONG *client_mac_lsw, ULONG *session_id)
1831 {
1832 
1833 
1834     /* Obtain the IP internal mutex before processing the IP event.  */
1835     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
1836 
1837     /* Check to see if PPPoE session is established.  */
1838     if ((pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_valid != NX_TRUE) ||
1839         (pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_session_id == 0))
1840     {
1841 
1842         /* Release the IP internal mutex.  */
1843         tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1844 
1845         return(NX_PPPOE_SERVER_SESSION_NOT_ESTABLISHED);
1846     }
1847 
1848     /* Yes, get the Client physical address MSW.  */
1849     if (client_mac_msw)
1850         *client_mac_msw = pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_physical_address_msw;
1851 
1852     /* Yes, get the Client physical address LSW.  */
1853     if (client_mac_lsw)
1854         *client_mac_lsw = pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_physical_address_lsw;
1855 
1856     /* Yes, get the Session ID.  */
1857     if (session_id)
1858         *session_id = pppoe_server_ptr -> nx_pppoe_client_session[session_index].nx_pppoe_session_id;
1859 
1860     /* Release the IP internal mutex.  */
1861     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
1862 
1863     /* Return status.  */
1864     return(NX_PPPOE_SERVER_SUCCESS);
1865 }
1866 
1867 
1868  /**************************************************************************/
1869 /*                                                                        */
1870 /*  FUNCTION                                               RELEASE        */
1871 /*                                                                        */
1872 /*    _nx_pppoe_server_packet_deferred_receive            PORTABLE C      */
1873 /*                                                           6.1          */
1874 /*  AUTHOR                                                                */
1875 /*                                                                        */
1876 /*    Yuxin Zhou, Microsoft Corporation                                   */
1877 /*                                                                        */
1878 /*  DESCRIPTION                                                           */
1879 /*                                                                        */
1880 /*    This function receives a packet from the link driver (usually the   */
1881 /*    link driver's input ISR) and places it in the deferred receive      */
1882 /*    packet queue.  This moves the minimal receive packet processing     */
1883 /*    from the ISR to the PPPoE helper thread.                            */
1884 /*                                                                        */
1885 /*  INPUT                                                                 */
1886 /*                                                                        */
1887 /*    packet_ptr                            Pointer to packet to receive  */
1888 /*                                                                        */
1889 /*  OUTPUT                                                                */
1890 /*                                                                        */
1891 /*    status                                Completion status             */
1892 /*                                                                        */
1893 /*  CALLS                                                                 */
1894 /*                                                                        */
1895 /*    tx_event_flags_set                    Set events for PPPoE thread   */
1896 /*                                                                        */
1897 /*  CALLED BY                                                             */
1898 /*                                                                        */
1899 /*    Application                                                         */
1900 /*                                                                        */
1901 /*  RELEASE HISTORY                                                       */
1902 /*                                                                        */
1903 /*    DATE              NAME                      DESCRIPTION             */
1904 /*                                                                        */
1905 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
1906 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
1907 /*                                            resulting in version 6.1    */
1908 /*                                                                        */
1909 /**************************************************************************/
_nx_pppoe_server_packet_deferred_receive(NX_PACKET * packet_ptr)1910 VOID  _nx_pppoe_server_packet_deferred_receive(NX_PACKET *packet_ptr)
1911 {
1912 
1913 TX_INTERRUPT_SAVE_AREA
1914 
1915 
1916     /* Check to see if PPPoE instance is created.  */
1917     if (_nx_pppoe_server_created_ptr == NX_NULL)
1918     {
1919 
1920         /* Release the packet.  */;
1921         nx_packet_release(packet_ptr);
1922 
1923         return;
1924     }
1925 
1926     /* Check to see if PPPoE is enabled.  */
1927     if (_nx_pppoe_server_created_ptr -> nx_pppoe_enabled != NX_TRUE)
1928     {
1929 
1930         /* Release the packet.  */;
1931         nx_packet_release(packet_ptr);
1932 
1933         return;
1934     }
1935 
1936     /* Disable interrupts.  */
1937     TX_DISABLE
1938 
1939     /* Check to see if the deferred processing queue is empty.  */
1940     if (_nx_pppoe_server_created_ptr -> nx_pppoe_deferred_received_packet_head)
1941     {
1942 
1943         /* Not empty, just place the packet at the end of the queue.  */
1944         (_nx_pppoe_server_created_ptr -> nx_pppoe_deferred_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
1945         packet_ptr -> nx_packet_queue_next =  NX_NULL;
1946         _nx_pppoe_server_created_ptr -> nx_pppoe_deferred_received_packet_tail = packet_ptr;
1947 
1948         /* Restore interrupts.  */
1949         TX_RESTORE
1950     }
1951     else
1952     {
1953 
1954         /* Empty deferred receive processing queue.  Just setup the head pointers and
1955            set the event flags to ensure the PPPoE helper thread looks at the deferred processing
1956            queue.  */
1957         _nx_pppoe_server_created_ptr -> nx_pppoe_deferred_received_packet_head = packet_ptr;
1958         _nx_pppoe_server_created_ptr -> nx_pppoe_deferred_received_packet_tail = packet_ptr;
1959         packet_ptr -> nx_packet_queue_next = NX_NULL;
1960 
1961         /* Restore interrupts.  */
1962         TX_RESTORE
1963 
1964         /* Wakeup PPPoE helper thread to process the PPPoE deferred receive.  */
1965         tx_event_flags_set(&(_nx_pppoe_server_created_ptr -> nx_pppoe_events), NX_PPPOE_SERVER_PACKET_RECEIVE_EVENT, TX_OR);
1966     }
1967 }
1968 
1969 
1970 /**************************************************************************/
1971 /*                                                                        */
1972 /*  FUNCTION                                               RELEASE        */
1973 /*                                                                        */
1974 /*    _nx_pppoe_server_thread_entry                       PORTABLE C      */
1975 /*                                                           6.1          */
1976 /*  AUTHOR                                                                */
1977 /*                                                                        */
1978 /*    Yuxin Zhou, Microsoft Corporation                                   */
1979 /*                                                                        */
1980 /*  DESCRIPTION                                                           */
1981 /*                                                                        */
1982 /*    This function is the entry point for each PPPoE's helper thread.    */
1983 /*    The PPPoE helper thread is responsible for processing PPPoE packet. */
1984 /*                                                                        */
1985 /*    Note that the priority of this function is determined by the PPPoE  */
1986 /*    create service.                                                     */
1987 /*                                                                        */
1988 /*  INPUT                                                                 */
1989 /*                                                                        */
1990 /*    pppoe_server_ptr_value                Pointer to PPPoE control block*/
1991 /*                                                                        */
1992 /*  OUTPUT                                                                */
1993 /*                                                                        */
1994 /*    status                                Completion status             */
1995 /*                                                                        */
1996 /*  CALLS                                                                 */
1997 /*                                                                        */
1998 /*    tx_event_flags_get                    Suspend on event flags that   */
1999 /*                                            are used to signal this     */
2000 /*                                            thread what to do           */
2001 /*    tx_mutex_get                          Obtain protection mutex       */
2002 /*    tx_mutex_put                          Release protection mutex      */
2003 /*    _nx_pppoe_server_packet_receive       PPPoE receive packet          */
2004 /*                                            processing                  */
2005 /*    nx_packet_release                     Release packet to packet pool */
2006 /*    (pppoe_link_driver)                   User supplied link driver     */
2007 /*                                                                        */
2008 /*  CALLED BY                                                             */
2009 /*                                                                        */
2010 /*    ThreadX Scheduler                                                   */
2011 /*                                                                        */
2012 /*  RELEASE HISTORY                                                       */
2013 /*                                                                        */
2014 /*    DATE              NAME                      DESCRIPTION             */
2015 /*                                                                        */
2016 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2017 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2018 /*                                            resulting in version 6.1    */
2019 /*                                                                        */
2020 /**************************************************************************/
_nx_pppoe_server_thread_entry(ULONG pppoe_server_ptr_value)2021 static VOID _nx_pppoe_server_thread_entry(ULONG pppoe_server_ptr_value)
2022 {
2023 
2024 TX_INTERRUPT_SAVE_AREA
2025 
2026 #ifdef NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE
2027 NX_IP_DRIVER        driver_request;
2028 #endif
2029 NX_PPPOE_SERVER    *pppoe_server_ptr;
2030 NX_IP              *ip_ptr;
2031 NX_PACKET          *packet_ptr;
2032 ULONG               pppoe_events;
2033 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2034 UINT                i;
2035 #endif
2036 
2037 
2038     /* Setup the PPPoE pointer.  */
2039     pppoe_server_ptr =  (NX_PPPOE_SERVER *) pppoe_server_ptr_value;
2040 
2041     /* Setup the IP pointer.  */
2042     ip_ptr = pppoe_server_ptr -> nx_pppoe_ip_ptr;
2043 
2044     /* Obtain the IP internal mutex before calling the driver.  */
2045     tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
2046 
2047 #ifdef NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE
2048 
2049     /* Initialize and enable the hardware for physical interface.  */
2050 
2051     /* Is this a valid interface with a link driver associated with it?  */
2052     if((pppoe_server_ptr -> nx_pppoe_interface_ptr -> nx_interface_valid) && (pppoe_server_ptr -> nx_pppoe_link_driver_entry))
2053     {
2054 
2055         /* Yes; attach the interface to the device. */
2056         driver_request.nx_ip_driver_ptr        = ip_ptr;
2057         driver_request.nx_ip_driver_command    = NX_LINK_INTERFACE_ATTACH;
2058         driver_request.nx_ip_driver_interface  = pppoe_server_ptr -> nx_pppoe_interface_ptr;
2059         (pppoe_server_ptr -> nx_pppoe_link_driver_entry) (&driver_request);
2060 
2061         /* Call the link driver to initialize the hardware. Among other
2062            responsibilities, the driver is required to provide the
2063            Maximum Transfer Unit (MTU) for the physical layer. The MTU
2064            should represent the actual physical layer transfer size
2065            less the physical layer headers and trailers.  */
2066         driver_request.nx_ip_driver_ptr     = ip_ptr;
2067         driver_request.nx_ip_driver_command = NX_LINK_INITIALIZE;
2068         (pppoe_server_ptr -> nx_pppoe_link_driver_entry) (&driver_request);
2069 
2070         /* Call the link driver again to enable the interface.  */
2071         driver_request.nx_ip_driver_ptr     = ip_ptr;
2072         driver_request.nx_ip_driver_command = NX_LINK_ENABLE;
2073         (pppoe_server_ptr -> nx_pppoe_link_driver_entry) (&driver_request);
2074 
2075         /* Indicate to the IP software that IP to physical mapping
2076            is not required.  */
2077         pppoe_server_ptr -> nx_pppoe_interface_ptr -> nx_interface_address_mapping_needed = NX_FALSE;
2078     }
2079 #endif
2080 
2081     /* Loop to continue processing incoming bytes.  */
2082     while(NX_FOREVER)
2083     {
2084 
2085 
2086         /* Release the IP internal mutex.  */
2087         tx_mutex_put(&(ip_ptr -> nx_ip_protection));
2088 
2089         /* Pickup IP event flags.  */
2090         tx_event_flags_get(&(pppoe_server_ptr -> nx_pppoe_events), NX_PPPOE_SERVER_ALL_EVENTS, TX_OR_CLEAR, &pppoe_events, NX_WAIT_FOREVER);
2091 
2092         /* Obtain the IP internal mutex before processing the IP event.  */
2093         tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
2094 
2095         /* Check for PPPoE event.  */
2096         if (pppoe_events & NX_PPPOE_SERVER_PACKET_RECEIVE_EVENT)
2097         {
2098 
2099             /* Loop to process all deferred packet requests.  */
2100             while (pppoe_server_ptr -> nx_pppoe_deferred_received_packet_head)
2101             {
2102 
2103                 /* Remove the first packet and process it!  */
2104 
2105                 /* Disable interrupts.  */
2106                 TX_DISABLE
2107 
2108                 /* Pickup the first packet.  */
2109                 packet_ptr =  pppoe_server_ptr -> nx_pppoe_deferred_received_packet_head;
2110 
2111                 /* Move the head pointer to the next packet.  */
2112                 pppoe_server_ptr -> nx_pppoe_deferred_received_packet_head =  packet_ptr -> nx_packet_queue_next;
2113 
2114                 /* Check for end of deferred processing queue.  */
2115                 if (pppoe_server_ptr -> nx_pppoe_deferred_received_packet_head == NX_NULL)
2116                 {
2117 
2118                     /* Yes, the queue is empty.  Set the tail pointer to NULL.  */
2119                     pppoe_server_ptr -> nx_pppoe_deferred_received_packet_tail =  NX_NULL;
2120                 }
2121 
2122                 /* Restore interrupts.  */
2123                 TX_RESTORE
2124 
2125 #ifndef NX_DISABLE_PACKET_CHAIN
2126 
2127                 /* Discard the chained packets.  */
2128                 if (packet_ptr -> nx_packet_next)
2129                 {
2130                     nx_packet_release(packet_ptr);
2131                     continue;
2132                 }
2133 #endif
2134 
2135                 /* Check for valid packet length.  */
2136                 if (packet_ptr -> nx_packet_length < NX_PPPOE_SERVER_OFFSET_PAYLOAD)
2137                 {
2138 
2139                     /* Release the packet.  */
2140                     nx_packet_release(packet_ptr);
2141                     return;
2142                 }
2143 
2144                 /* Check the packet interface.  */
2145                 if ((packet_ptr -> nx_packet_ip_interface != NX_NULL) &&
2146                     (packet_ptr -> nx_packet_ip_interface != pppoe_server_ptr -> nx_pppoe_interface_ptr))
2147                 {
2148                     nx_packet_release(packet_ptr);
2149                     continue;
2150                 }
2151 
2152                 /* Call the actual PPPoE Server packet receive function.  */
2153                 _nx_pppoe_server_packet_receive(pppoe_server_ptr, packet_ptr);
2154             }
2155         }
2156 
2157 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2158         /* Check for PPPoE Session Receive event.  */
2159         if (pppoe_events & NX_PPPOE_SERVER_SESSION_RECEIVE_EVENT)
2160         {
2161 
2162             for(i = 0; i < NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER; i ++)
2163             {
2164 
2165                 /* Check if this session is valid.  */
2166                 if (pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_valid != NX_TRUE)
2167                     continue;
2168 
2169                 /* Check if this session is ready to receive the packet.  */
2170                 if (pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_packet_receive_stopped == NX_TRUE)
2171                     continue;
2172 
2173                 /* Check if this session queued the packets.  */
2174                 if (pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_deferred_received_packet_head)
2175                 {
2176 
2177                     /* Remove the first packet and process it!  */
2178 
2179                     /* Disable interrupts.  */
2180                     TX_DISABLE
2181 
2182                     /* Pickup the first packet.  */
2183                     packet_ptr = pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_deferred_received_packet_head;
2184 
2185                     /* Move the head pointer to the next packet.  */
2186                     pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_deferred_received_packet_head = packet_ptr -> nx_packet_queue_next;
2187 
2188                     /* Check for end of deferred processing queue.  */
2189                     if (pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_deferred_received_packet_head == NX_NULL)
2190                     {
2191 
2192                         /* Yes, the queue is empty.  Set the tail pointer to NULL.  */
2193                         pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_deferred_received_packet_tail = NX_NULL;
2194                     }
2195 
2196                     /* Restore interrupts.  */
2197                     TX_RESTORE
2198 
2199                     /* Set the flag to stop receive the next packet.  */
2200                     pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_packet_receive_stopped = NX_TRUE;
2201 
2202                     /* Check the PPPoE receive function.  */
2203                     if (_nx_pppoe_server_created_ptr -> nx_pppoe_data_receive_notify)
2204                     {
2205 
2206                         /* Call the function to receive the data frame.  */
2207                         _nx_pppoe_server_created_ptr -> nx_pppoe_data_receive_notify(i, packet_ptr -> nx_packet_length, packet_ptr -> nx_packet_prepend_ptr, (UINT)(packet_ptr));
2208                     }
2209                 }
2210             }
2211         }
2212 #endif
2213     }
2214 }
2215 
2216 
2217 /**************************************************************************/
2218 /*                                                                        */
2219 /*  FUNCTION                                               RELEASE        */
2220 /*                                                                        */
2221 /*    _nx_pppoe_server_packet_receive                     PORTABLE C      */
2222 /*                                                           6.1          */
2223 /*  AUTHOR                                                                */
2224 /*                                                                        */
2225 /*    Yuxin Zhou, Microsoft Corporation                                   */
2226 /*                                                                        */
2227 /*  DESCRIPTION                                                           */
2228 /*                                                                        */
2229 /*    This function receives a PPPoE packet from the PPPoE deferred       */
2230 /*    processing queue.                                                   */
2231 /*                                                                        */
2232 /*  INPUT                                                                 */
2233 /*                                                                        */
2234 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
2235 /*    packet_ptr                            Pointer to packet to receive  */
2236 /*                                                                        */
2237 /*  OUTPUT                                                                */
2238 /*                                                                        */
2239 /*    status                                Completion status             */
2240 /*                                                                        */
2241 /*  CALLS                                                                 */
2242 /*                                                                        */
2243 /*    nx_packet_release                     Release packet to packet pool */
2244 /*    _nx_pppoe_server_data_get             Get the PPPoE data            */
2245 /*    _nx_pppoe_server_discovery_packet_process                           */
2246 /*                                          Process discovery packet      */
2247 /*    _nx_pppoe_server_session_packet_process                             */
2248 /*                                          Process session packet        */
2249 /*                                                                        */
2250 /*  CALLED BY                                                             */
2251 /*                                                                        */
2252 /*    _nx_pppoe_server_thread_entry                                       */
2253 /*                                                                        */
2254 /*  RELEASE HISTORY                                                       */
2255 /*                                                                        */
2256 /*    DATE              NAME                      DESCRIPTION             */
2257 /*                                                                        */
2258 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2259 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2260 /*                                            resulting in version 6.1    */
2261 /*                                                                        */
2262 /**************************************************************************/
_nx_pppoe_server_packet_receive(NX_PPPOE_SERVER * pppoe_server_ptr,NX_PACKET * packet_ptr)2263 VOID  _nx_pppoe_server_packet_receive(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PACKET *packet_ptr)
2264 {
2265 
2266 UCHAR                      *ethernet_header_ptr;
2267 ULONG                       server_mac_msw;
2268 ULONG                       server_mac_lsw;
2269 ULONG                       client_mac_msw;
2270 ULONG                       client_mac_lsw;
2271 UINT                        ethernet_type;
2272 UINT                        is_broadcast = NX_FALSE;
2273 
2274     /* Set up UCHAR pointer to ethernet header to extract client hardware address
2275        which we will use as the client's unique identifier.  */
2276     ethernet_header_ptr = packet_ptr -> nx_packet_prepend_ptr - NX_PPPOE_SERVER_ETHER_HEADER_SIZE;
2277 
2278     /* Pickup the MSW and LSW of the destination MAC address.  */
2279     server_mac_msw = (((ULONG) ethernet_header_ptr[0]) << 8)  | ((ULONG) ethernet_header_ptr[1]);
2280     server_mac_lsw = (((ULONG) ethernet_header_ptr[2]) << 24) | (((ULONG) ethernet_header_ptr[3]) << 16) |
2281                      (((ULONG) ethernet_header_ptr[4]) << 8)  | ((ULONG) ethernet_header_ptr[5]);
2282 
2283     /* Check the server hardware (mac address) field is filled in. */
2284     if ((server_mac_msw == 0) && (server_mac_lsw == 0))
2285     {
2286 
2287         /* Release the packet.  */
2288         nx_packet_release(packet_ptr);
2289         return;
2290     }
2291 
2292     /* Check if it is a broadcast message.  */
2293     if ((server_mac_msw == 0xFFFF) && (server_mac_lsw == 0xFFFFFFFF))
2294         is_broadcast = NX_TRUE;
2295 
2296     /* Pickup the MSW and LSW of the source MAC address.  */
2297     client_mac_msw = (((ULONG) ethernet_header_ptr[6]) << 8)  | ((ULONG) ethernet_header_ptr[7]);
2298     client_mac_lsw = (((ULONG) ethernet_header_ptr[8]) << 24) | (((ULONG) ethernet_header_ptr[9]) << 16) |
2299                      (((ULONG) ethernet_header_ptr[10]) << 8)  | ((ULONG) ethernet_header_ptr[11]);
2300 
2301     /* Check the client hardware (mac address) field is filled in. */
2302     if ((client_mac_msw == 0) && (client_mac_lsw == 0))
2303     {
2304 
2305         /* Release the packet.  */
2306         nx_packet_release(packet_ptr);
2307         return;
2308     }
2309 
2310     /* Get the ethernet type.  */
2311     ethernet_type = _nx_pppoe_server_data_get(ethernet_header_ptr + 12, 2);
2312 
2313     /* Process the packet according to packet type. */
2314     if(ethernet_type == NX_PPPOE_SERVER_ETHER_TYPE_DISCOVERY)
2315     {
2316 
2317         /* Process the discovery packet.  */
2318         _nx_pppoe_server_discovery_packet_process(pppoe_server_ptr, packet_ptr, client_mac_msw, client_mac_lsw, is_broadcast);
2319     }
2320     else if(ethernet_type == NX_PPPOE_SERVER_ETHER_TYPE_SESSION)
2321     {
2322 
2323         /* Session Stage, all Ethernet packets are unicast.  */
2324         if (is_broadcast == NX_TRUE)
2325         {
2326 
2327             /* Release the packet.  */
2328             nx_packet_release(packet_ptr);
2329             return;
2330         }
2331 
2332         /* Process the session packet.  */
2333         _nx_pppoe_server_session_packet_process(pppoe_server_ptr, packet_ptr, client_mac_msw, client_mac_lsw);
2334     }
2335     else
2336     {
2337 
2338         /* Relase the packet.  */
2339         nx_packet_release(packet_ptr);
2340     }
2341 
2342     return;
2343 }
2344 
2345 
2346 /**************************************************************************/
2347 /*                                                                        */
2348 /*  FUNCTION                                               RELEASE        */
2349 /*                                                                        */
2350 /*    _nx_pppoe_server_discovery_packet_process           PORTABLE C      */
2351 /*                                                           6.1          */
2352 /*  AUTHOR                                                                */
2353 /*                                                                        */
2354 /*    Yuxin Zhou, Microsoft Corporation                                   */
2355 /*                                                                        */
2356 /*  DESCRIPTION                                                           */
2357 /*                                                                        */
2358 /*    This function processes an incoming discovery packet.               */
2359 /*                                                                        */
2360 /*  INPUT                                                                 */
2361 /*                                                                        */
2362 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
2363 /*    packet_ptr                            Pointer to packet to receive  */
2364 /*    client_mac_msw                        Client physical address MSW   */
2365 /*    client_mac_lsw                        Client physical address LSW   */
2366 /*    is_broadcast                          Broadcast flag                */
2367 /*                                                                        */
2368 /*  OUTPUT                                                                */
2369 /*                                                                        */
2370 /*    status                                Completion status             */
2371 /*                                                                        */
2372 /*  CALLS                                                                 */
2373 /*                                                                        */
2374 /*    nx_packet_release                     Release packet to packet pool */
2375 /*    _nx_pppoe_server_data_get             Get the PPPoE data            */
2376 /*    _nx_pppoe_server_tag_process          Process PPPoE tags            */
2377 /*    _nx_pppoe_server_discovery_send       Send discovery packet         */
2378 /*    _nx_pppoe_server_session_find         Find the PPPoE session        */
2379 /*    _nx_pppoe_server_session_cleanup      Cleanup the PPPoE session     */
2380 /*                                                                        */
2381 /*  CALLED BY                                                             */
2382 /*                                                                        */
2383 /*    _nx_pppoe_server_packet_receive       Receive the PPPoE packet      */
2384 /*                                                                        */
2385 /*  RELEASE HISTORY                                                       */
2386 /*                                                                        */
2387 /*    DATE              NAME                      DESCRIPTION             */
2388 /*                                                                        */
2389 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2390 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
2391 /*                                            packet length verification, */
2392 /*                                            resulting in version 6.1    */
2393 /*                                                                        */
2394 /**************************************************************************/
_nx_pppoe_server_discovery_packet_process(NX_PPPOE_SERVER * pppoe_server_ptr,NX_PACKET * packet_ptr,ULONG client_mac_msw,ULONG client_mac_lsw,UINT is_broadcast)2395 VOID  _nx_pppoe_server_discovery_packet_process(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PACKET *packet_ptr, ULONG client_mac_msw, ULONG client_mac_lsw, UINT is_broadcast)
2396 {
2397 
2398 UCHAR                      *pppoe_header_ptr;
2399 ULONG                       ver_type;
2400 ULONG                       code;
2401 ULONG                       session_id;
2402 ULONG                       length;
2403 UINT                        status;
2404 UCHAR                      *tag_ptr;
2405 UINT                        session_index = 0;
2406 NX_PPPOE_CLIENT_SESSION    *client_session_ptr = NX_NULL;
2407 
2408 
2409     /* Setup the PPPoE header.  */
2410     pppoe_header_ptr = packet_ptr -> nx_packet_prepend_ptr;
2411 
2412     /* Pickup the version and type.  */
2413     ver_type = _nx_pppoe_server_data_get(pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_VER_TYPE, 1);
2414 
2415     /* Check the version and type.  */
2416     if (ver_type != NX_PPPOE_SERVER_VERSION_TYPE)
2417     {
2418 
2419         /* Release the packet.  */
2420         nx_packet_release(packet_ptr);
2421         return;
2422     }
2423 
2424     /* Pickup the code.  */
2425     code = _nx_pppoe_server_data_get(pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_CODE, 1);
2426 
2427     /* Check the code.  */
2428     if ((code != NX_PPPOE_SERVER_CODE_PADI) &&
2429         (code != NX_PPPOE_SERVER_CODE_PADR) &&
2430         (code != NX_PPPOE_SERVER_CODE_PADT))
2431     {
2432 
2433         /* Release the packet.  */
2434         nx_packet_release(packet_ptr);
2435         return;
2436     }
2437 
2438     /* For PADI, the destination address should be broadcast.
2439        For PADR and PART, the destination address should be unicast.  */
2440     if (((code == NX_PPPOE_SERVER_CODE_PADI) && (is_broadcast != NX_TRUE)) ||
2441         ((code != NX_PPPOE_SERVER_CODE_PADI) && (is_broadcast == NX_TRUE)))
2442     {
2443 
2444         /* Release the packet.  */
2445         nx_packet_release(packet_ptr);
2446         return;
2447     }
2448 
2449     /* Pickup the session id.  */
2450     session_id = _nx_pppoe_server_data_get(pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_SESSION_ID, 2);
2451 
2452     /* Check the session id.
2453        Session ID must be zero for PADI and PADR,
2454        Session ID must be not zero for PADT.  */
2455     if (((code != NX_PPPOE_SERVER_CODE_PADT) && (session_id != 0)) ||
2456         ((code == NX_PPPOE_SERVER_CODE_PADT) && (session_id == 0)))
2457     {
2458 
2459         /* Release the packet.  */
2460         nx_packet_release(packet_ptr);
2461         return;
2462     }
2463 
2464     /* Find the PPPoE Session.  */
2465     status = _nx_pppoe_server_session_find(pppoe_server_ptr, client_mac_msw, client_mac_lsw, session_id, &session_index, &client_session_ptr);
2466 
2467     /* Check the status.  */
2468     if (status)
2469     {
2470 
2471         /* Release the packet.  */
2472         nx_packet_release(packet_ptr);
2473         return;
2474     }
2475 
2476     /* Pickup the length of tags.  */
2477     length = _nx_pppoe_server_data_get(pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_LENGTH, 2);
2478 
2479     /* Check for valid payload.  */
2480     if (length + NX_PPPOE_SERVER_OFFSET_PAYLOAD > packet_ptr -> nx_packet_length)
2481     {
2482 
2483         /* Release the packet.  */
2484         nx_packet_release(packet_ptr);
2485         return;
2486     }
2487 
2488     /* Set the tag pointer.  */
2489     tag_ptr = pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_PAYLOAD;
2490 
2491     /* Process the tag.  */
2492     status = _nx_pppoe_server_tag_process(pppoe_server_ptr, client_session_ptr, code, tag_ptr, length);
2493 
2494     /* Now we can release the packet. */
2495     nx_packet_release(packet_ptr);
2496 
2497     /* Check the status.  */
2498     if (status)
2499     {
2500 
2501         /* If the Access Concentrator does not like the Service-Name in the PADR,
2502            then it MUST reply with a PADS containing a TAG of TAG_TYPE Service-Name-Error (and any number of other TAG types).
2503            In this case the SESSION_ID MUST be set to 0x0000. RFC2516, Section5.4, Page6.  */
2504         if ((status == NX_PPPOE_SERVER_SERVICE_NAME_ERROR) && (code == NX_PPPOE_SERVER_CODE_PADR))
2505         {
2506 
2507             /* Clear the session id.  */
2508             client_session_ptr -> nx_pppoe_session_id = 0;
2509 
2510             /* Send PADS.  */
2511             _nx_pppoe_server_discovery_send(pppoe_server_ptr, client_session_ptr, NX_PPPOE_SERVER_CODE_PADS);
2512         }
2513 
2514         /* Cleanup the PPPoE session.  */
2515         _nx_pppoe_server_session_cleanup(client_session_ptr);
2516 
2517         return;
2518     }
2519 
2520     /* Check the code value.  */
2521     if (code == NX_PPPOE_SERVER_CODE_PADI)
2522     {
2523 
2524         /* It is PPPoE Active Discovery Initiation packet.  */
2525         if (pppoe_server_ptr -> nx_pppoe_discover_initiation_notify)
2526         {
2527 
2528             /* Call discover initiation notify function.  */
2529             pppoe_server_ptr -> nx_pppoe_discover_initiation_notify(session_index);
2530 
2531 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2532             /* Send PPPoE Active Discover Offer packet in PppDiscoverCnf().  */
2533             return;
2534 #endif
2535         }
2536 
2537         /* Send PPPoE Active Discovery Offer packet.  */
2538         _nx_pppoe_server_discovery_send(pppoe_server_ptr, client_session_ptr, NX_PPPOE_SERVER_CODE_PADO);
2539     }
2540     else if (code == NX_PPPOE_SERVER_CODE_PADR)
2541     {
2542 
2543         /* Generate the unique session id.  */
2544         if (client_session_ptr -> nx_pppoe_session_id == 0)
2545         {
2546 
2547             /* The Session ID should not be zero and 0xFFFF.
2548                RFC2516, Section4, Page4.  */
2549             if ((pppoe_server_ptr -> nx_pppoe_session_id == 0) ||
2550                 (pppoe_server_ptr -> nx_pppoe_session_id == 0xFFFF))
2551                 pppoe_server_ptr -> nx_pppoe_session_id = 1;
2552 
2553             /* Setup the session id.  */
2554             client_session_ptr -> nx_pppoe_session_id = pppoe_server_ptr -> nx_pppoe_session_id;
2555 
2556             /* Update the session id for next client session.  */
2557             pppoe_server_ptr -> nx_pppoe_session_id++;
2558         }
2559 
2560         /* It is PPPoE Active Discovery Request packet.  */
2561         if (pppoe_server_ptr -> nx_pppoe_discover_request_notify)
2562         {
2563 
2564             /* Call discover reqest notify function.  */
2565             if (client_session_ptr -> nx_pppoe_service_name == NX_NULL)
2566             {
2567                 pppoe_server_ptr -> nx_pppoe_discover_request_notify(session_index, 0, NX_NULL);
2568             }
2569             else
2570             {
2571                 /* Check service name length.  */
2572                 _nx_utility_string_length_check((char*)client_session_ptr -> nx_pppoe_service_name, (UINT *)&length, NX_MAX_STRING_LENGTH);
2573 
2574                 pppoe_server_ptr -> nx_pppoe_discover_request_notify(session_index, length, client_session_ptr -> nx_pppoe_service_name);
2575             }
2576 
2577 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2578             /* Send PPPoE Active Discover Session-confirmation packet in PppOpenCnf().  */
2579             return;
2580 #endif
2581         }
2582 
2583         /* Send PPPoE Active Discovery Session-confirmation packet.  */
2584         _nx_pppoe_server_discovery_send(pppoe_server_ptr, client_session_ptr, NX_PPPOE_SERVER_CODE_PADS);
2585     }
2586     else if (code == NX_PPPOE_SERVER_CODE_PADT)
2587     {
2588 
2589 #ifndef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2590         /* Cleanup the PPPoE session.  */
2591         _nx_pppoe_server_session_cleanup(client_session_ptr);
2592 #endif
2593 
2594         /* It is PPPoE Active Discovery Terminate packet.  */
2595         if (pppoe_server_ptr -> nx_pppoe_discover_terminate_notify)
2596         {
2597 
2598             /* Call discover terminate notify function.  */
2599             pppoe_server_ptr -> nx_pppoe_discover_terminate_notify(session_index);
2600         }
2601     }
2602 }
2603 
2604 
2605 /**************************************************************************/
2606 /*                                                                        */
2607 /*  FUNCTION                                               RELEASE        */
2608 /*                                                                        */
2609 /*    _nx_pppoe_server_session_packet_process             PORTABLE C      */
2610 /*                                                           6.1          */
2611 /*  AUTHOR                                                                */
2612 /*                                                                        */
2613 /*    Yuxin Zhou, Microsoft Corporation                                   */
2614 /*                                                                        */
2615 /*  DESCRIPTION                                                           */
2616 /*                                                                        */
2617 /*    This function processes an incoming session packet.                 */
2618 /*                                                                        */
2619 /*  INPUT                                                                 */
2620 /*                                                                        */
2621 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
2622 /*    packet_ptr                            Pointer to packet to receive  */
2623 /*    client_mac_msw                        Client physical address MSW   */
2624 /*    client_mac_lsw                        Client physical address LSW   */
2625 /*                                                                        */
2626 /*  OUTPUT                                                                */
2627 /*                                                                        */
2628 /*    status                                Completion status             */
2629 /*                                                                        */
2630 /*  CALLS                                                                 */
2631 /*                                                                        */
2632 /*    nx_packet_release                     Release packet to packet pool */
2633 /*    _nx_pppoe_server_data_get             Get the PPPoE data            */
2634 /*    _nx_pppoe_server_session_find         Find the PPPoE session        */
2635 /*                                                                        */
2636 /*  CALLED BY                                                             */
2637 /*                                                                        */
2638 /*    _nx_pppoe_server_packet_receive       Receive the PPPoE packet      */
2639 /*                                                                        */
2640 /*  RELEASE HISTORY                                                       */
2641 /*                                                                        */
2642 /*    DATE              NAME                      DESCRIPTION             */
2643 /*                                                                        */
2644 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2645 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2646 /*                                            resulting in version 6.1    */
2647 /*                                                                        */
2648 /**************************************************************************/
_nx_pppoe_server_session_packet_process(NX_PPPOE_SERVER * pppoe_server_ptr,NX_PACKET * packet_ptr,ULONG client_mac_msw,ULONG client_mac_lsw)2649 static VOID  _nx_pppoe_server_session_packet_process(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PACKET *packet_ptr, ULONG client_mac_msw, ULONG client_mac_lsw)
2650 {
2651 
2652 UCHAR                      *pppoe_header_ptr;
2653 ULONG                       ver_type;
2654 ULONG                       code;
2655 ULONG                       session_id;
2656 ULONG                       length;
2657 UINT                        status;
2658 UINT                        session_index = 0;
2659 NX_PPPOE_CLIENT_SESSION    *client_session_ptr = NX_NULL;
2660 
2661 
2662     /* Setup the PPPoE header.  */
2663     pppoe_header_ptr = packet_ptr -> nx_packet_prepend_ptr;
2664 
2665     /* Pickup the version and type.  */
2666     ver_type = _nx_pppoe_server_data_get(pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_VER_TYPE, 1);
2667 
2668     /* Check the version and type.  */
2669     if (ver_type != NX_PPPOE_SERVER_VERSION_TYPE)
2670     {
2671 
2672         /* Release the packet.  */
2673         nx_packet_release(packet_ptr);
2674         return;
2675     }
2676 
2677     /* Pickup the code.  */
2678     code = _nx_pppoe_server_data_get(pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_CODE, 1);
2679 
2680     /* Check the code.  */
2681     if (code != NX_PPPOE_SERVER_CODE_ZERO)
2682     {
2683 
2684         /* Release the packet.  */
2685         nx_packet_release(packet_ptr);
2686         return;
2687     }
2688 
2689     /* Pickup the session id.  */
2690     session_id = _nx_pppoe_server_data_get(pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_SESSION_ID, 2);
2691 
2692     /* Check the session id.  */
2693     if (session_id == 0)
2694     {
2695 
2696         /* Release the packet.  */
2697         nx_packet_release(packet_ptr);
2698         return;
2699     }
2700 
2701     /* Setup the prepend pointer to point the payload of PPPoE.  */
2702     packet_ptr -> nx_packet_prepend_ptr += NX_PPPOE_SERVER_OFFSET_PAYLOAD;
2703     packet_ptr -> nx_packet_length -= NX_PPPOE_SERVER_OFFSET_PAYLOAD;
2704 
2705     /* Look up the PPPoE session by physical address and interface index in Client Records table. */
2706     status = _nx_pppoe_server_session_find(pppoe_server_ptr, client_mac_msw, client_mac_lsw, session_id, &session_index, &client_session_ptr);
2707 
2708     /* Check the status.  */
2709     if (status)
2710     {
2711 
2712         /* Release the packet.  */
2713         nx_packet_release(packet_ptr);
2714         return;
2715     }
2716 
2717     /* Pickup the length of payload.  */
2718     length = _nx_pppoe_server_data_get(pppoe_header_ptr + NX_PPPOE_SERVER_OFFSET_LENGTH, 2);
2719 
2720     /* Check for valid payload.  */
2721     if (length > packet_ptr -> nx_packet_length)
2722     {
2723 
2724         /* Release the packet.  */
2725         nx_packet_release(packet_ptr);
2726         return;
2727     }
2728 
2729     /* Remove the Ethernet padding.  */
2730     if (length < packet_ptr -> nx_packet_length)
2731     {
2732         packet_ptr -> nx_packet_append_ptr -= (packet_ptr -> nx_packet_length - length);
2733         packet_ptr -> nx_packet_length -= (packet_ptr -> nx_packet_length - length);
2734     }
2735 
2736 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2737 
2738     /* Check to see if the deferred processing queue is empty.  */
2739     if (client_session_ptr -> nx_pppoe_deferred_received_packet_head)
2740     {
2741 
2742         /* Not empty, just place the packet at the end of the queue.  */
2743         (client_session_ptr -> nx_pppoe_deferred_received_packet_tail) -> nx_packet_queue_next = packet_ptr;
2744         packet_ptr -> nx_packet_queue_next =  NX_NULL;
2745         client_session_ptr -> nx_pppoe_deferred_received_packet_tail = packet_ptr;
2746 
2747         /* Return.  */
2748         return;
2749     }
2750     else
2751     {
2752 
2753         /* Check the packet receive flag.  */
2754         if (client_session_ptr -> nx_pppoe_packet_receive_stopped == NX_TRUE)
2755         {
2756 
2757             /* Empty deferred receive processing queue.  Just setup the head pointers and
2758                set the event flags to ensure the PPPoE helper thread looks at the deferred processing queue.  */
2759             client_session_ptr -> nx_pppoe_deferred_received_packet_head = packet_ptr;
2760             client_session_ptr -> nx_pppoe_deferred_received_packet_tail = packet_ptr;
2761             packet_ptr -> nx_packet_queue_next = NX_NULL;
2762 
2763             /* Return.  */
2764             return;
2765         }
2766     }
2767 
2768     /* Set the flag to stop receive the next packet.  */
2769     client_session_ptr -> nx_pppoe_packet_receive_stopped = NX_TRUE;
2770 #endif
2771 
2772     /* Check the PPPoE receive function.  */
2773     if (pppoe_server_ptr -> nx_pppoe_data_receive_notify)
2774     {
2775 
2776         /* Call the function to receive the data frame.
2777            Notice: the receive function must release this packet.  */
2778         pppoe_server_ptr -> nx_pppoe_data_receive_notify(session_index, length, packet_ptr -> nx_packet_prepend_ptr, (UINT)(packet_ptr));
2779     }
2780     else
2781     {
2782 
2783         /* Release the packet.  */
2784         nx_packet_release(packet_ptr);
2785     }
2786 
2787     return;
2788 }
2789 
2790 
2791 /**************************************************************************/
2792 /*                                                                        */
2793 /*  FUNCTION                                               RELEASE        */
2794 /*                                                                        */
2795 /*    _nx_pppoe_server_discovery_send                     PORTABLE C      */
2796 /*                                                           6.1.4        */
2797 /*  AUTHOR                                                                */
2798 /*                                                                        */
2799 /*    Yuxin Zhou, Microsoft Corporation                                   */
2800 /*                                                                        */
2801 /*  DESCRIPTION                                                           */
2802 /*                                                                        */
2803 /*    This function sends a PPPoE discovery packet.                       */
2804 /*                                                                        */
2805 /*  INPUT                                                                 */
2806 /*                                                                        */
2807 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
2808 /*    client_session_ptr                    Pointer to Client Session     */
2809 /*    code                                  PPPoE code                    */
2810 /*                                                                        */
2811 /*  OUTPUT                                                                */
2812 /*                                                                        */
2813 /*    status                                Completion status             */
2814 /*                                                                        */
2815 /*  CALLS                                                                 */
2816 /*                                                                        */
2817 /*    tx_mutex_get                          Obtain a protection mutex     */
2818 /*    tx_mutex_put                          Release protection mutex      */
2819 /*    nx_packet_allocate                    Allocate a packet for the     */
2820 /*                                            PPPoE Discovery             */
2821 /*    nx_packet_release                     Release packet to packet pool */
2822 /*    _nx_pppoe_server_data_add             Add PPPoE data                */
2823 /*    _nx_pppoe_server_tag_string_add       Add PPPoE tag                 */
2824 /*    _nx_pppoe_server_packet_send          Send out PPPoE packet         */
2825 /*    _nx_pppoe_server_session_find         Find the PPPoE session        */
2826 /*                                                                        */
2827 /*  CALLED BY                                                             */
2828 /*                                                                        */
2829 /*    _nx_pppoe_server_session_terminate    Terminate the PPPoE session   */
2830 /*    _nx_pppoe_server_discovery_packet_process                           */
2831 /*                                          Process PPPoE Discovery packet*/
2832 /*                                                                        */
2833 /*  RELEASE HISTORY                                                       */
2834 /*                                                                        */
2835 /*    DATE              NAME                      DESCRIPTION             */
2836 /*                                                                        */
2837 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
2838 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
2839 /*                                            resulting in version 6.1    */
2840 /*  02-02-2021     Yuxin Zhou               Modified comment(s),          */
2841 /*                                            fixed the compiler errors,  */
2842 /*                                            resulting in version 6.1.4  */
2843 /*                                                                        */
2844 /**************************************************************************/
_nx_pppoe_server_discovery_send(NX_PPPOE_SERVER * pppoe_server_ptr,NX_PPPOE_CLIENT_SESSION * client_session_ptr,UINT code)2845 static UINT    _nx_pppoe_server_discovery_send(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PPPOE_CLIENT_SESSION *client_session_ptr, UINT code)
2846 {
2847 
2848 NX_PACKET       *packet_ptr;
2849 UCHAR           *work_ptr;
2850 UINT            status;
2851 UINT            index = 0;
2852 UINT            tag_length;
2853 UINT            service_name_index = 0;
2854 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2855 UCHAR          *service_name_ptr;
2856 #endif
2857 
2858 
2859     /* Release the mutex before a blocking call. */
2860     tx_mutex_put(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
2861 
2862     /* Allocate a PPPoE packet.  */
2863     status =  nx_packet_allocate(pppoe_server_ptr -> nx_pppoe_packet_pool_ptr, &packet_ptr, NX_PHYSICAL_HEADER, NX_PPPOE_SERVER_PACKET_TIMEOUT);
2864 
2865     /* Was the packet allocation successful?  */
2866     if (status != NX_SUCCESS)
2867     {
2868 
2869         /* Return status.  */
2870         return(status);
2871     }
2872 
2873     /* Obtain the IP internal mutex.  */
2874     tx_mutex_get(&(pppoe_server_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
2875 
2876     /* Set the work pointer.  */
2877     work_ptr = packet_ptr -> nx_packet_prepend_ptr;
2878 
2879     /* First skip the PPPoE header.  */
2880     index += NX_PPPOE_SERVER_OFFSET_PAYLOAD;
2881 
2882     /* The PPPoE payload contains zero or more TAGs.  A TAG is a TLV (type-length-value) construct and is defined as follows.  */
2883 
2884     /*                      1                   2                   3
2885      *  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
2886      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2887      * |          TAG_TYPE              |         TAG_LENGTH           |
2888      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2889      * |          TAG_VALUE  ...
2890      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2891     */
2892 
2893     /* Add the PPPoE tags.  */
2894     if (code == NX_PPPOE_SERVER_CODE_PADO)
2895     {
2896 
2897         /* The PADO packet MUST contain one AC-Name TAG containing the Access Concentrator's name. RFC2516, Section 5.2, Page6. */
2898 
2899         /* Added the AC-Name tag.  */
2900         if (pppoe_server_ptr -> nx_pppoe_ac_name)
2901         {
2902 
2903             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_AC_NAME, pppoe_server_ptr -> nx_pppoe_ac_name_length, (UCHAR *)(pppoe_server_ptr -> nx_pppoe_ac_name), &index);
2904         }
2905         else
2906         {
2907 
2908             /* If user does not separately set Access Concentrator name, will use PPPoE server name as Access Concentrator name.*/
2909             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_AC_NAME, pppoe_server_ptr -> nx_pppoe_name_length, (UCHAR *)(pppoe_server_ptr -> nx_pppoe_name), &index);
2910         }
2911 
2912         /* The PADO packet MUST contain a Service-Name TAG identical to the one in the PADI,
2913            and any number of other Service-Name TAGs indicating other services. RFC2516, Section 5.2, Page6.  */
2914 
2915         /* Added a Service-Name TAG identical to the one in the PADI.  */
2916         if  (client_session_ptr -> nx_pppoe_service_name)
2917         {
2918 
2919 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2920             /* Set the service name pointer.  */
2921             service_name_ptr = client_session_ptr -> nx_pppoe_service_name;
2922 
2923             /* Loop to add service name that user configured.  */
2924             while(service_name_index < client_session_ptr -> nx_pppoe_service_name_length)
2925             {
2926 
2927                 /* Get the service name.  */
2928                 if (_nx_utility_string_length_check((char *)(service_name_ptr), &tag_length, NX_MAX_STRING_LENGTH))
2929                 {
2930                     nx_packet_release(packet_ptr);
2931                     return(NX_PPPOE_SERVER_SERVICE_NAME_ERROR);
2932                 }
2933 
2934                 /* Added the Service-Name tag.  */
2935                 _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_SERVICE_NAME, tag_length, service_name_ptr, &index);
2936 
2937                 /* Update the service name pointer, length + null-terminated.  */
2938                 service_name_ptr += (tag_length + 1);
2939                 service_name_index += (tag_length + 1);
2940             }
2941 #else
2942             /* Calculate the name length.  */
2943             if (_nx_utility_string_length_check((char *)(client_session_ptr -> nx_pppoe_service_name), &tag_length, NX_MAX_STRING_LENGTH))
2944             {
2945                 nx_packet_release(packet_ptr);
2946                 return(NX_PPPOE_SERVER_SERVICE_NAME_ERROR);
2947             }
2948 
2949             /* Added the Service-Name tag.  */
2950             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_SERVICE_NAME, tag_length, client_session_ptr -> nx_pppoe_service_name, &index);
2951 #endif
2952         }
2953         else
2954         {
2955 
2956             /* Added the Service-Name tag.  */
2957             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_SERVICE_NAME, 0, NX_NULL, &index);
2958         }
2959 
2960 #ifndef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
2961         /* Add any number of other Service-Name TAGs indicating other services.   */
2962         if  (pppoe_server_ptr -> nx_pppoe_service_name_count)
2963         {
2964 
2965             /* The PADO packet can contain any number of Service-Name TAGs.  */
2966             for (service_name_index = 0; service_name_index < pppoe_server_ptr -> nx_pppoe_service_name_count; service_name_index ++)
2967             {
2968 
2969                 /* Check if this Service-Name has been added.  */
2970                 if (pppoe_server_ptr -> nx_pppoe_service_name[service_name_index] == client_session_ptr -> nx_pppoe_service_name)
2971                     continue;
2972 
2973                 /* Calculate the name length.  */
2974                 if (_nx_utility_string_length_check((char *)(pppoe_server_ptr -> nx_pppoe_service_name[service_name_index]), &tag_length, NX_MAX_STRING_LENGTH))
2975                 {
2976                     nx_packet_release(packet_ptr);
2977                     return(NX_PPPOE_SERVER_SERVICE_NAME_ERROR);
2978                 }
2979 
2980                 /* Added the Service-Name tag.  */
2981                 _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_SERVICE_NAME, tag_length, (UCHAR *)(pppoe_server_ptr -> nx_pppoe_service_name[service_name_index]), &index);
2982             }
2983         }
2984 #endif
2985 
2986         /* If the Access Concentrator receives this Host-Uniq TAG, it MUST include the TAG unmodified in associated PADO or PADS response.
2987            RFC2516, Appendix A, Host-Uniq.  */
2988         if  (client_session_ptr -> nx_pppoe_host_uniq_size)
2989         {
2990 
2991             /* Added the Host-Uniq.  */
2992             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_HOST_UNIQ, client_session_ptr -> nx_pppoe_host_uniq_size, client_session_ptr -> nx_pppoe_host_uniq, &index);
2993         }
2994 
2995         /* If either the Host or Access Concentrator receives this Relay-Session-Id TAG, they MUST include it unmodified in any discovery packet they send as a response.
2996            RFC2516, Appendix A, Relay-Session-Id.  */
2997         if  (client_session_ptr -> nx_pppoe_relay_session_id_size)
2998         {
2999 
3000             /* Added the Host-Uniq.  */
3001             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_RELAY_SESSION_ID, client_session_ptr -> nx_pppoe_relay_session_id_size, client_session_ptr -> nx_pppoe_relay_session_id, &index);
3002         }
3003     }
3004     else if (code == NX_PPPOE_SERVER_CODE_PADS)
3005     {
3006 
3007         /* Check the error.  */
3008         if (client_session_ptr -> nx_pppoe_error_flag & NX_PPPOE_SERVER_ERROR_SERVICE_NAME)
3009         {
3010 
3011             /* Added Service-Name-Error tag.  */
3012             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_SERVICE_NAME_ERROR, 0, NX_NULL, &index);
3013         }
3014 
3015         /* The PADS packet MUST contain one exactly one TAG of TAG_TYPE Service-Name. RFC2516, Section 5.4, Page6 */
3016 
3017         /* Check the service name.  */
3018         if  (client_session_ptr -> nx_pppoe_service_name)
3019         {
3020 
3021             /* Calculate the name length.  */
3022             if (_nx_utility_string_length_check((char *)(client_session_ptr -> nx_pppoe_service_name), &tag_length, NX_MAX_STRING_LENGTH))
3023             {
3024                 nx_packet_release(packet_ptr);
3025                 return(NX_PPPOE_SERVER_SERVICE_NAME_ERROR);
3026             }
3027 
3028             /* Added the Service-Name tag.  */
3029             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_SERVICE_NAME, tag_length, client_session_ptr -> nx_pppoe_service_name, &index);
3030         }
3031         else
3032         {
3033 
3034             /* Added the Service-Name tag.  */
3035             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_SERVICE_NAME, 0, NX_NULL, &index);
3036         }
3037 
3038         /* If the Access Concentrator receives this Host-Uniq TAG, it MUST include the TAG unmodified in associated PADO or PADS response.
3039            RFC2516, Appendix A, Host-Uniq.  */
3040         if  (client_session_ptr -> nx_pppoe_host_uniq_size)
3041         {
3042 
3043             /* Added the Host-Uniq.  */
3044             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_HOST_UNIQ, client_session_ptr -> nx_pppoe_host_uniq_size, client_session_ptr -> nx_pppoe_host_uniq, &index);
3045         }
3046 
3047         /* If either the Host or Access Concentrator receives this Relay-Session-Id TAG, they MUST include it unmodified in any discovery packet they send as a response.
3048            RFC2516, Appendix A, Relay-Session-Id.  */
3049         if  (client_session_ptr -> nx_pppoe_relay_session_id_size)
3050         {
3051 
3052             /* Added the Host-Uniq.  */
3053             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_RELAY_SESSION_ID, client_session_ptr -> nx_pppoe_relay_session_id_size, client_session_ptr -> nx_pppoe_relay_session_id, &index);
3054         }
3055     }
3056 
3057 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
3058     else if (code == NX_PPPOE_SERVER_CODE_PADT)
3059     {
3060 
3061         /* Check the Generic-Error.  */
3062         if (client_session_ptr -> nx_pppoe_generic_error)
3063         {
3064 
3065             /* Calculate the Generic-Error string length.  */
3066             if (_nx_utility_string_length_check((char *)(client_session_ptr -> nx_pppoe_generic_error), &tag_length, NX_MAX_STRING_LENGTH))
3067             {
3068                 nx_packet_release(packet_ptr);
3069                 return(NX_SIZE_ERROR);
3070             }
3071 
3072             /* Added the Generic-Error.  */
3073             _nx_pppoe_server_tag_string_add(work_ptr, NX_PPPOE_SERVER_TAG_TYPE_GENERIC_ERROR, tag_length, client_session_ptr -> nx_pppoe_generic_error, &index);
3074         }
3075     }
3076 #endif
3077 
3078     /* Add the PPPoE header.  */
3079     /*
3080      *  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
3081      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3082      * |  VER | TYPE  |      CODE       |         SESSION_ID           |
3083      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3084      * |           LENGTH               |          payload
3085      * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3086     */
3087 
3088     /* Add version and type.  */
3089     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_VER_TYPE, 1, NX_PPPOE_SERVER_VERSION_TYPE);
3090 
3091     /* Add code.  */
3092     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_CODE, 1, code);
3093 
3094     /* Add the Session id.  */
3095     if (code == NX_PPPOE_SERVER_CODE_PADO)
3096     {
3097 
3098         /* Add session id.  */
3099         _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_SESSION_ID, 2, 0);
3100     }
3101     else
3102     {
3103 
3104         /* Add session id.  */
3105         _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_SESSION_ID, 2, client_session_ptr -> nx_pppoe_session_id);
3106     }
3107 
3108     /* Add length.  */
3109     _nx_pppoe_server_data_add(work_ptr + NX_PPPOE_SERVER_OFFSET_LENGTH, 2, (index - NX_PPPOE_SERVER_OFFSET_PAYLOAD));
3110 
3111     /* Update the append pointer and length.  */
3112     packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + index;
3113     packet_ptr -> nx_packet_length = index;
3114 
3115     /* Send PPPoE session packet.  */
3116     _nx_pppoe_server_packet_send(pppoe_server_ptr, client_session_ptr, packet_ptr, NX_LINK_PPPOE_DISCOVERY_SEND);
3117 
3118     /* Return success.  */
3119     return(NX_PPPOE_SERVER_SUCCESS);
3120 }
3121 
3122 
3123 /**************************************************************************/
3124 /*                                                                        */
3125 /*  FUNCTION                                               RELEASE        */
3126 /*                                                                        */
3127 /*    _nx_pppoe_server_packet_send                        PORTABLE C      */
3128 /*                                                           6.1          */
3129 /*  AUTHOR                                                                */
3130 /*                                                                        */
3131 /*    Yuxin Zhou, Microsoft Corporation                                   */
3132 /*                                                                        */
3133 /*  DESCRIPTION                                                           */
3134 /*                                                                        */
3135 /*    This function sends a PPPoE packet to the appropriate link driver.  */
3136 /*                                                                        */
3137 /*  INPUT                                                                 */
3138 /*                                                                        */
3139 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
3140 /*    client_session_ptr                    Pointer to Client Session     */
3141 /*    packet_ptr                            Pointer to packet to send     */
3142 /*    command                               Driver command                */
3143 /*                                                                        */
3144 /*  OUTPUT                                                                */
3145 /*                                                                        */
3146 /*    status                                Completion status             */
3147 /*                                                                        */
3148 /*  CALLS                                                                 */
3149 /*                                                                        */
3150 /*    (ip_link_driver)                      User supplied link driver     */
3151 /*                                                                        */
3152 /*  CALLED BY                                                             */
3153 /*                                                                        */
3154 /*    _nx_pppoe_server_discovery_send       Send PPPoE Discovery packet   */
3155 /*    _nx_pppoe_server_session_send         Send PPPoE Session packet     */
3156 /*                                                                        */
3157 /*  RELEASE HISTORY                                                       */
3158 /*                                                                        */
3159 /*    DATE              NAME                      DESCRIPTION             */
3160 /*                                                                        */
3161 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3162 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3163 /*                                            resulting in version 6.1    */
3164 /*                                                                        */
3165 /**************************************************************************/
_nx_pppoe_server_packet_send(NX_PPPOE_SERVER * pppoe_server_ptr,NX_PPPOE_CLIENT_SESSION * client_session_ptr,NX_PACKET * packet_ptr,UINT command)3166 static VOID    _nx_pppoe_server_packet_send(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PPPOE_CLIENT_SESSION *client_session_ptr, NX_PACKET *packet_ptr, UINT command)
3167 {
3168 
3169 NX_IP_DRIVER                driver_request;
3170 
3171 
3172     /* Initialize the driver request. */
3173     driver_request.nx_ip_driver_ptr =                   pppoe_server_ptr -> nx_pppoe_ip_ptr;
3174     driver_request.nx_ip_driver_packet =                packet_ptr;
3175     driver_request.nx_ip_driver_interface =             pppoe_server_ptr -> nx_pppoe_interface_ptr;
3176     driver_request.nx_ip_driver_physical_address_msw =  client_session_ptr -> nx_pppoe_physical_address_msw;
3177     driver_request.nx_ip_driver_physical_address_lsw =  client_session_ptr -> nx_pppoe_physical_address_lsw;
3178     driver_request.nx_ip_driver_command =               command;
3179 
3180     /* Sendout the PPPoE packet.  */
3181     (pppoe_server_ptr -> nx_pppoe_link_driver_entry) (&driver_request);
3182 }
3183 
3184 
3185 /**************************************************************************/
3186 /*                                                                        */
3187 /*  FUNCTION                                               RELEASE        */
3188 /*                                                                        */
3189 /*    _nx_pppoe_server_tag_process                        PORTABLE C      */
3190 /*                                                           6.1.4        */
3191 /*  AUTHOR                                                                */
3192 /*                                                                        */
3193 /*    Yuxin Zhou, Microsoft Corporation                                   */
3194 /*                                                                        */
3195 /*  DESCRIPTION                                                           */
3196 /*                                                                        */
3197 /*    This function processes tags of PPPoE packet.                       */
3198 /*                                                                        */
3199 /*  INPUT                                                                 */
3200 /*                                                                        */
3201 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
3202 /*    client_session_ptr                    Pointer to Client Session     */
3203 /*    code                                  PPPoE code                    */
3204 /*    tag_ptr                               Pointer to PPPoE tag          */
3205 /*    length                                Length of PPPoe tags          */
3206 /*                                                                        */
3207 /*  OUTPUT                                                                */
3208 /*                                                                        */
3209 /*    status                                Completion status             */
3210 /*                                                                        */
3211 /*  CALLS                                                                 */
3212 /*                                                                        */
3213 /*    _nx_pppoe_server_data_get             Get the PPPoE data            */
3214 /*                                                                        */
3215 /*  CALLED BY                                                             */
3216 /*                                                                        */
3217 /*    _nx_pppoe_server_discovery_packet_process                           */
3218 /*                                          Process PPPoE Discovery packet*/
3219 /*                                                                        */
3220 /*  RELEASE HISTORY                                                       */
3221 /*                                                                        */
3222 /*    DATE              NAME                      DESCRIPTION             */
3223 /*                                                                        */
3224 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3225 /*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
3226 /*                                            packet length verification, */
3227 /*                                            verified memcpy use cases,  */
3228 /*                                            resulting in version 6.1    */
3229 /*  02-02-2021     Yuxin Zhou               Modified comment(s), improved */
3230 /*                                            string length verification, */
3231 /*                                            fixed the compiler errors,  */
3232 /*                                            resulting in version 6.1.4  */
3233 /*                                                                        */
3234 /**************************************************************************/
_nx_pppoe_server_tag_process(NX_PPPOE_SERVER * pppoe_server_ptr,NX_PPPOE_CLIENT_SESSION * client_session_ptr,UINT code,UCHAR * tag_ptr,ULONG length)3235 static UINT  _nx_pppoe_server_tag_process(NX_PPPOE_SERVER *pppoe_server_ptr, NX_PPPOE_CLIENT_SESSION *client_session_ptr, UINT code, UCHAR *tag_ptr, ULONG length)
3236 {
3237 
3238 ULONG           tag_type;
3239 ULONG           tag_length;
3240 UINT            tag_index = 0;
3241 UINT            tag_service_name_count = 0;
3242 UINT            tag_service_name_valid = NX_FALSE;
3243 UINT            service_name_index = 0;
3244 UINT            service_name_length;
3245 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
3246 UCHAR          *service_name_ptr;
3247 #endif
3248 
3249     /* Initialize the value.  */
3250     client_session_ptr -> nx_pppoe_host_uniq_size = 0;
3251     client_session_ptr -> nx_pppoe_relay_session_id_size = 0;
3252     client_session_ptr -> nx_pppoe_error_flag = 0;
3253 #ifndef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
3254     client_session_ptr -> nx_pppoe_service_name = NX_NULL;
3255 #endif
3256 
3257 
3258     /* Loop to process the tag.  */
3259     while (tag_index + 4 <= length)
3260     {
3261 
3262         /* Pickup the tag type.  */
3263         tag_type = _nx_pppoe_server_data_get(tag_ptr + tag_index, 2);
3264 
3265         /* Update the index.  */
3266         tag_index += 2;
3267 
3268         /* Pickup the tag length.  */
3269         tag_length = _nx_pppoe_server_data_get(tag_ptr + tag_index, 2);
3270 
3271         /* Update the index.  */
3272         tag_index += 2;
3273 
3274         /* Check for valid tag length.  */
3275         if ((tag_index + tag_length) > length)
3276         {
3277             return(NX_PPPOE_SERVER_PACKET_PAYLOAD_ERROR);
3278         }
3279 
3280         /* Process the option type. */
3281         switch (tag_type)
3282         {
3283 
3284             case NX_PPPOE_SERVER_TAG_TYPE_END_OF_LIST:
3285             {
3286 
3287                 /* End tag.  */
3288                 break;
3289             }
3290             case NX_PPPOE_SERVER_TAG_TYPE_SERVICE_NAME:
3291             {
3292 
3293                 /* Service name tag.  */
3294                 tag_service_name_count ++;
3295 
3296 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
3297                 if (code == NX_PPPOE_SERVER_CODE_PADI)
3298                 {
3299 
3300                     /* The service name of incoming PADI must match the default service name of PPPoE.  */
3301                     /* Check the tag length.  */
3302                     if (tag_length == 0)
3303                     {
3304 
3305                         /* Check the default service name.  */
3306                         if (pppoe_server_ptr -> nx_pppoe_service_name_count == 0)
3307                             tag_service_name_valid = NX_TRUE;
3308                     }
3309                     else
3310                     {
3311 
3312                         /* Loop to find the service name.  */
3313                         while (service_name_index < pppoe_server_ptr -> nx_pppoe_service_name_count)
3314                         {
3315 
3316                             /* Get the length of service name.  */
3317                             if (_nx_utility_string_length_check((char *)(pppoe_server_ptr -> nx_pppoe_service_name[service_name_index]),
3318                                                                 &service_name_length, tag_length))
3319                             {
3320                                 service_name_index++;
3321                                 continue;
3322                             }
3323 
3324                             /* Compare the same service name with PPPoE Service Name.  */
3325                             if ((service_name_length == tag_length) &&
3326                                 (!memcmp(tag_ptr + tag_index, (pppoe_server_ptr -> nx_pppoe_service_name[service_name_index]), tag_length)))
3327                             {
3328                                 tag_service_name_valid = NX_TRUE;
3329                                 client_session_ptr -> nx_pppoe_service_name = pppoe_server_ptr -> nx_pppoe_service_name[service_name_index];
3330                                 client_session_ptr -> nx_pppoe_service_name_length = service_name_length;
3331                                 break;
3332                             }
3333                             service_name_index ++;
3334                         }
3335                     }
3336                 }
3337                 else if (code == NX_PPPOE_SERVER_CODE_PADR)
3338                 {
3339 
3340                     /* Compare the service name with session service name.  */
3341                     /* Check the tag length.  */
3342                     if ((tag_length == 0) && (client_session_ptr -> nx_pppoe_service_name_length == 0))
3343                     {
3344 
3345                         /* Update the information.  */
3346                         tag_service_name_valid = NX_TRUE;
3347                         client_session_ptr -> nx_pppoe_service_name = NX_NULL;
3348                         client_session_ptr -> nx_pppoe_service_name_length = 0;
3349                         break;
3350                     }
3351 
3352                     /* Set the service name pointer.  */
3353                     service_name_ptr = client_session_ptr -> nx_pppoe_service_name;
3354 
3355                     /* Loop to compare the service name with session service name.  */
3356                     while(service_name_index < client_session_ptr -> nx_pppoe_service_name_length)
3357                     {
3358 
3359                         /* Get the service name.  */
3360                         if (_nx_utility_string_length_check((char *)(service_name_ptr), &service_name_length, NX_MAX_STRING_LENGTH))
3361                         {
3362                             return(NX_PPPOE_SERVER_SERVICE_NAME_ERROR);
3363                         }
3364 
3365                         /* Check the tag length.  */
3366                         if ((tag_length == 0) && (service_name_length == 0))
3367                         {
3368                             tag_service_name_valid = NX_TRUE;
3369                         }
3370                         else if ((tag_length != 0) && (tag_length == service_name_length))
3371                         {
3372 
3373                             /* Compare the service name.  */
3374                             if (!memcmp(tag_ptr + tag_index, service_name_ptr, tag_length))
3375                                 tag_service_name_valid = NX_TRUE;
3376                         }
3377 
3378                         /* Update the service name information for PADS.  */
3379                         if (tag_service_name_valid == NX_TRUE)
3380                         {
3381                             client_session_ptr -> nx_pppoe_service_name = service_name_ptr;
3382                             client_session_ptr -> nx_pppoe_service_name_length = service_name_length;
3383                             break;
3384                         }
3385 
3386                         /* Update the service name pointer, length + null-terminated.  */
3387                         service_name_ptr += (service_name_length + 1);
3388                         service_name_index += (service_name_length + 1);
3389                     }
3390                 }
3391 #else
3392 
3393                 /* Check the tag length.  */
3394                 if (tag_length == 0)
3395                 {
3396 
3397                     /* When the tag length is zero this tag is used to indicate that any service is acceptable.  */
3398                     tag_service_name_valid = NX_TRUE;
3399                     break;
3400                 }
3401 
3402                 /* Compare the service name with PPPoE Service name.  */
3403                 while (service_name_index < pppoe_server_ptr -> nx_pppoe_service_name_count)
3404                 {
3405 
3406                     /* Get the length of service name.  */
3407                     if (_nx_utility_string_length_check((char *)(pppoe_server_ptr -> nx_pppoe_service_name[service_name_index]),
3408                                                         &service_name_length, tag_length))
3409                     {
3410                         service_name_index++;
3411                         continue;
3412                     }
3413 
3414                     /* Find the same service name.  */
3415                     if ((service_name_length == tag_length) &&
3416                         (!memcmp(tag_ptr + tag_index, (pppoe_server_ptr -> nx_pppoe_service_name[service_name_index]), tag_length)))
3417                     {
3418 
3419                         /* Update the information.  */
3420                         tag_service_name_valid = NX_TRUE;
3421                         client_session_ptr -> nx_pppoe_service_name = pppoe_server_ptr -> nx_pppoe_service_name[service_name_index];
3422                         break;
3423                     }
3424                     service_name_index ++;
3425                 }
3426 #endif
3427                 break;
3428             }
3429             case NX_PPPOE_SERVER_TAG_TYPE_AC_NAME:
3430             {
3431 
3432                 if (pppoe_server_ptr -> nx_pppoe_ac_name)
3433                 {
3434                     /* Check the access concentrator name.  */
3435                     if ((pppoe_server_ptr -> nx_pppoe_ac_name_length != tag_length) ||
3436                         (memcmp(tag_ptr + tag_index, (pppoe_server_ptr -> nx_pppoe_ac_name), tag_length)))
3437                     {
3438 
3439                         return(NX_PPPOE_SERVER_AC_NAME_ERROR);
3440                     }
3441                 }
3442                 else
3443                 {
3444                     /* If user does not separately set Access Concentrator name, will use PPPoE server name as Access Concentrator name.*/
3445                     if ((pppoe_server_ptr -> nx_pppoe_name_length != tag_length) ||
3446                         (memcmp(tag_ptr + tag_index, (pppoe_server_ptr -> nx_pppoe_name), tag_length)))
3447                     {
3448 
3449                         return(NX_PPPOE_SERVER_AC_NAME_ERROR);
3450                     }
3451                 }
3452                 break;
3453             }
3454             case NX_PPPOE_SERVER_TAG_TYPE_HOST_UNIQ:
3455             {
3456 
3457                 /* Check the cache for Host-Uniq.  */
3458                 if (tag_length> NX_PPPOE_SERVER_MAX_HOST_UNIQ_SIZE)
3459                     return (NX_PPPOE_SERVER_HOST_UNIQ_CACHE_ERROR);
3460 
3461                 /* Save the Host-Uniq.  */
3462                 memcpy(client_session_ptr -> nx_pppoe_host_uniq, tag_ptr + tag_index, tag_length); /* Use case of memcpy is verified. */
3463 
3464                 /* Set the Host-Uniq size.  */
3465                 client_session_ptr -> nx_pppoe_host_uniq_size = tag_length;
3466                 break;
3467             }
3468             case NX_PPPOE_SERVER_TAG_TYPE_RELAY_SESSION_ID:
3469             {
3470 
3471                 /* Check the cache for Relay-Session_Id.  */
3472                 if (tag_length> NX_PPPOE_SERVER_MAX_RELAY_SESSION_ID_SIZE)
3473                     return (NX_PPPOE_SERVER_RELAY_SESSION_ID_CACHE_ERROR);
3474 
3475                 /* Save the Relay-Session_Id.  */
3476                 memcpy(client_session_ptr -> nx_pppoe_relay_session_id, tag_ptr + tag_index, tag_length); /* Use case of memcpy is verified. */
3477 
3478                 /* Set the Relay-Session_Id size.  */
3479                 client_session_ptr -> nx_pppoe_relay_session_id_size = tag_length;
3480                 break;
3481             }
3482             default:
3483                 break;
3484         }
3485 
3486         /* Move to the next tag. */
3487         tag_index += tag_length;
3488     }
3489 
3490     /* Check the code.  */
3491     if ((code == NX_PPPOE_SERVER_CODE_PADI) || (code == NX_PPPOE_SERVER_CODE_PADR))
3492     {
3493 
3494         /* The PADI and PADR packet MUST contains exactly one TAG of TAG_TYPE Service- Name,  RFC2516  */
3495         if ((tag_service_name_count != 1) || (tag_service_name_valid != NX_TRUE))
3496         {
3497 
3498             /* Set the service name error flag.  */
3499             client_session_ptr -> nx_pppoe_error_flag |= NX_PPPOE_SERVER_ERROR_SERVICE_NAME;
3500 
3501             /* Service-Name tag error.  */
3502             return(NX_PPPOE_SERVER_SERVICE_NAME_ERROR);
3503         }
3504     }
3505 
3506     /* TAGs processed.  */
3507     return(NX_PPPOE_SERVER_SUCCESS);
3508 }
3509 
3510 
3511 /**************************************************************************/
3512 /*                                                                        */
3513 /*  FUNCTION                                               RELEASE        */
3514 /*                                                                        */
3515 /*    _nx_pppoe_server_data_get                           PORTABLE C      */
3516 /*                                                           6.1          */
3517 /*  AUTHOR                                                                */
3518 /*                                                                        */
3519 /*    Yuxin Zhou, Microsoft Corporation                                   */
3520 /*                                                                        */
3521 /*  DESCRIPTION                                                           */
3522 /*                                                                        */
3523 /*    This function gets the datas of PPPoE packet.                       */
3524 /*                                                                        */
3525 /*  INPUT                                                                 */
3526 /*                                                                        */
3527 /*    data                                  Pointer to buffer data        */
3528 /*    size                                  Size of data value            */
3529 /*                                                                        */
3530 /*  OUTPUT                                                                */
3531 /*                                                                        */
3532 /*    status                                Completion status             */
3533 /*                                                                        */
3534 /*  CALLS                                                                 */
3535 /*                                                                        */
3536 /*    None                                                                */
3537 /*                                                                        */
3538 /*  CALLED BY                                                             */
3539 /*                                                                        */
3540 /*    _nx_pppoe_server_packet_receive       Receive the PPPoE packet      */
3541 /*    _nx_pppoe_server_discovery_packet_process                           */
3542 /*                                          Process PPPoE Discovery packet*/
3543 /*    _nx_pppoe_server_session_packet_process                             */
3544 /*                                          Process PPPoE Session packet  */
3545 /*    _nx_pppoe_server_tag_process          Process PPPoE TAGs            */
3546 /*                                                                        */
3547 /*  RELEASE HISTORY                                                       */
3548 /*                                                                        */
3549 /*    DATE              NAME                      DESCRIPTION             */
3550 /*                                                                        */
3551 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3552 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3553 /*                                            resulting in version 6.1    */
3554 /*                                                                        */
3555 /**************************************************************************/
_nx_pppoe_server_data_get(UCHAR * data,UINT size)3556 static ULONG  _nx_pppoe_server_data_get(UCHAR *data, UINT size)
3557 {
3558 
3559 ULONG   value = 0;
3560 
3561 
3562     /* Process the data retrieval request.  */
3563     while (size-- > 0)
3564     {
3565 
3566         /* Build return value.  */
3567         value = (value << 8) | *data++;
3568     }
3569 
3570     /* Return value.  */
3571     return(value);
3572 }
3573 
3574 
3575 /**************************************************************************/
3576 /*                                                                        */
3577 /*  FUNCTION                                               RELEASE        */
3578 /*                                                                        */
3579 /*    _nx_pppoe_server_data_add                           PORTABLE C      */
3580 /*                                                           6.1          */
3581 /*  AUTHOR                                                                */
3582 /*                                                                        */
3583 /*    Yuxin Zhou, Microsoft Corporation                                   */
3584 /*                                                                        */
3585 /*  DESCRIPTION                                                           */
3586 /*                                                                        */
3587 /*    This function adds the datas into PPPoE packet.                     */
3588 /*                                                                        */
3589 /*  INPUT                                                                 */
3590 /*                                                                        */
3591 /*    data                                  Pointer to buffer data        */
3592 /*    size                                  Size of data value            */
3593 /*    value                                 Value to add                  */
3594 /*                                                                        */
3595 /*  OUTPUT                                                                */
3596 /*                                                                        */
3597 /*    status                                Completion status             */
3598 /*                                                                        */
3599 /*  CALLS                                                                 */
3600 /*                                                                        */
3601 /*    None                                                                */
3602 /*                                                                        */
3603 /*  CALLED BY                                                             */
3604 /*                                                                        */
3605 /*    _nx_pppoe_server_discovery_send       Send PPPoE Discovery packet   */
3606 /*    _nx_pppoe_server_session_send         Send PPPoE Session packet     */
3607 /*    _nx_pppoe_server_tag_string_add       Add PPPoE string TAG          */
3608 /*                                                                        */
3609 /*  RELEASE HISTORY                                                       */
3610 /*                                                                        */
3611 /*    DATE              NAME                      DESCRIPTION             */
3612 /*                                                                        */
3613 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3614 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3615 /*                                            resulting in version 6.1    */
3616 /*                                                                        */
3617 /**************************************************************************/
_nx_pppoe_server_data_add(UCHAR * data,UINT size,ULONG value)3618 static VOID  _nx_pppoe_server_data_add(UCHAR *data, UINT size, ULONG value)
3619 {
3620 
3621     /* Make sure that data is left justified.  */
3622     switch (size)
3623     {
3624 
3625         case 1:
3626 
3627             value <<= 24;
3628             break;
3629 
3630         case 2:
3631 
3632             value <<= 16;
3633             break;
3634 
3635         case 3:
3636 
3637             value <<= 8;
3638             break;
3639 
3640         default:
3641             break;
3642     }
3643 
3644     /* Store the value.  */
3645     while (size-- > 0)
3646     {
3647 
3648         *data = (UCHAR) ((value >> 24) & 0xff);
3649         data++;
3650         value <<= 8;
3651     }
3652 }
3653 
3654 
3655 /**************************************************************************/
3656 /*                                                                        */
3657 /*  FUNCTION                                               RELEASE        */
3658 /*                                                                        */
3659 /*    _nx_pppoe_server_string_add                         PORTABLE C      */
3660 /*                                                           6.1          */
3661 /*  AUTHOR                                                                */
3662 /*                                                                        */
3663 /*    Yuxin Zhou, Microsoft Corporation                                   */
3664 /*                                                                        */
3665 /*  DESCRIPTION                                                           */
3666 /*                                                                        */
3667 /*    This function adds the string into PPPoE packet.                    */
3668 /*                                                                        */
3669 /*  INPUT                                                                 */
3670 /*                                                                        */
3671 /*    dest                                  Pointer to destination buffer */
3672 /*    source                                Pointer to source buffer      */
3673 /*    size                                  Number of bytes to add        */
3674 /*                                                                        */
3675 /*  OUTPUT                                                                */
3676 /*                                                                        */
3677 /*    status                                Completion status             */
3678 /*                                                                        */
3679 /*  CALLS                                                                 */
3680 /*                                                                        */
3681 /*    None                                                                */
3682 /*                                                                        */
3683 /*  CALLED BY                                                             */
3684 /*                                                                        */
3685 /*    _nx_pppoe_server_tag_string_add       Add PPPoE string TAG          */
3686 /*                                                                        */
3687 /*  RELEASE HISTORY                                                       */
3688 /*                                                                        */
3689 /*    DATE              NAME                      DESCRIPTION             */
3690 /*                                                                        */
3691 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3692 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3693 /*                                            resulting in version 6.1    */
3694 /*                                                                        */
3695 /**************************************************************************/
_nx_pppoe_server_string_add(UCHAR * dest,UCHAR * source,UINT size)3696 static VOID  _nx_pppoe_server_string_add(UCHAR *dest, UCHAR *source, UINT size)
3697 {
3698 
3699     /* Loop to copy all bytes.  */
3700     while (size-- > 0)
3701     {
3702 
3703         /* Copy a byte.  */
3704         *dest++ = *source++;
3705     }
3706 }
3707 
3708 
3709 /**************************************************************************/
3710 /*                                                                        */
3711 /*  FUNCTION                                               RELEASE        */
3712 /*                                                                        */
3713 /*    _nx_pppoe_server_tag_string_add                     PORTABLE C      */
3714 /*                                                           6.1          */
3715 /*  AUTHOR                                                                */
3716 /*                                                                        */
3717 /*    Yuxin Zhou, Microsoft Corporation                                   */
3718 /*                                                                        */
3719 /*  DESCRIPTION                                                           */
3720 /*                                                                        */
3721 /*    This function adds the TAG with string into PPPoE packet.           */
3722 /*                                                                        */
3723 /*  INPUT                                                                 */
3724 /*                                                                        */
3725 /*    data_ptr                              Pointer to data buffer        */
3726 /*    tag_type                              Type of TAG                   */
3727 /*    tag_length                            Length of TAG                 */
3728 /*    tag_value_string                      String value of TAG to add    */
3729 /*    index                                 Location into data buffer     */
3730 /*                                             to write data              */
3731 /*                                                                        */
3732 /*  OUTPUT                                                                */
3733 /*                                                                        */
3734 /*    status                                Completion status             */
3735 /*                                                                        */
3736 /*  CALLS                                                                 */
3737 /*                                                                        */
3738 /*    _nx_pppoe_server_data_add             Add PPPoE data                */
3739 /*    _nx_pppoe_server_string_add           Add PPPoE string data         */
3740 /*                                                                        */
3741 /*  CALLED BY                                                             */
3742 /*                                                                        */
3743 /*    _nx_pppoe_server_discovery_send       Send PPPoE Discovery packet   */
3744 /*                                                                        */
3745 /*  RELEASE HISTORY                                                       */
3746 /*                                                                        */
3747 /*    DATE              NAME                      DESCRIPTION             */
3748 /*                                                                        */
3749 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3750 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3751 /*                                            resulting in version 6.1    */
3752 /*                                                                        */
3753 /**************************************************************************/
_nx_pppoe_server_tag_string_add(UCHAR * data_ptr,UINT tag_type,UINT tag_length,UCHAR * tag_value_string,UINT * index)3754 static UINT  _nx_pppoe_server_tag_string_add(UCHAR *data_ptr, UINT tag_type, UINT tag_length, UCHAR *tag_value_string, UINT *index)
3755 {
3756 
3757     /* Add the tag type.  */
3758     _nx_pppoe_server_data_add(data_ptr + (*index), 2, tag_type);
3759     (*index) += 2;
3760 
3761     /* Add the tag length.  */
3762     _nx_pppoe_server_data_add(data_ptr + (*index), 2, tag_length);
3763     (*index) += 2;
3764 
3765     /* Add the tag value string.  */
3766     _nx_pppoe_server_string_add(data_ptr + (*index), tag_value_string, tag_length);
3767     (*index) += tag_length;
3768 
3769     /* Return a successful completion.  */
3770     return(NX_PPPOE_SERVER_SUCCESS);
3771 }
3772 
3773 
3774 /**************************************************************************/
3775 /*                                                                        */
3776 /*  FUNCTION                                               RELEASE        */
3777 /*                                                                        */
3778 /*    _nx_pppoe_server_session_find                       PORTABLE C      */
3779 /*                                                           6.1          */
3780 /*  AUTHOR                                                                */
3781 /*                                                                        */
3782 /*    Yuxin Zhou, Microsoft Corporation                                   */
3783 /*                                                                        */
3784 /*  DESCRIPTION                                                           */
3785 /*                                                                        */
3786 /*    This function finds a PPPoE session by the client hardware mac      */
3787 /*    address and session id. In Discovery Stage, match the client harware*/
3788 /*    address, if not match, mark one available session. In Session Stage,*/
3789 /*    match the client harware address and session id, if not match,      */
3790 /*    return NX_PPPOE_CLIENT_SESSION_NOT_FOUND.                           */
3791 /*                                                                        */
3792 /*  INPUT                                                                 */
3793 /*                                                                        */
3794 /*    pppoe_server_ptr                      Pointer to PPPoE control block*/
3795 /*    client_mac_msw                        Client physical address MSW   */
3796 /*    client_mac_lsw                        Client physical address LSW   */
3797 /*    session_id                            Session ID                    */
3798 /*    session_index                         Session Index                 */
3799 /*    client_session_ptr                    Pointer to Client Session     */
3800 /*                                                                        */
3801 /*  OUTPUT                                                                */
3802 /*                                                                        */
3803 /*    status                                Completion status             */
3804 /*                                                                        */
3805 /*  CALLS                                                                 */
3806 /*                                                                        */
3807 /*    None                                                                */
3808 /*                                                                        */
3809 /*  CALLED BY                                                             */
3810 /*                                                                        */
3811 /*    _nx_pppoe_server_discovery_packet_process                           */
3812 /*                                          Process PPPoE Discovery packet*/
3813 /*    _nx_pppoe_server_session_packet_process                             */
3814 /*                                          Process PPPoE Session packet  */
3815 /*                                                                        */
3816 /*  RELEASE HISTORY                                                       */
3817 /*                                                                        */
3818 /*    DATE              NAME                      DESCRIPTION             */
3819 /*                                                                        */
3820 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3821 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3822 /*                                            resulting in version 6.1    */
3823 /*                                                                        */
3824 /**************************************************************************/
_nx_pppoe_server_session_find(NX_PPPOE_SERVER * pppoe_server_ptr,ULONG client_mac_msw,ULONG client_mac_lsw,ULONG session_id,UINT * session_index,NX_PPPOE_CLIENT_SESSION ** client_session_ptr)3825 static UINT  _nx_pppoe_server_session_find(NX_PPPOE_SERVER *pppoe_server_ptr, ULONG client_mac_msw, ULONG client_mac_lsw,
3826                                            ULONG session_id, UINT *session_index, NX_PPPOE_CLIENT_SESSION **client_session_ptr)
3827 {
3828 
3829 UINT                i;
3830 UINT                available_index;
3831 
3832 
3833     /* Initialize the value.   */
3834     i = 0;
3835     available_index = NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER;
3836 
3837     for(i = 0; i < NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER; i ++)
3838     {
3839 
3840         /* Check if this session is valid.  */
3841         if (pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_valid == NX_TRUE)
3842         {
3843 
3844             /* Compare the physical address.  */
3845             if ((pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_physical_address_msw != client_mac_msw) ||
3846                 (pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_physical_address_lsw != client_mac_lsw))
3847                 continue;
3848 
3849             /* If the session id is not zero, means the session has been established.  */
3850             if (session_id != 0)
3851             {
3852 
3853                 /* Compare the session id.  */
3854                 if (pppoe_server_ptr -> nx_pppoe_client_session[i].nx_pppoe_session_id != session_id)
3855                     continue;
3856             }
3857 
3858             /* Yes, find the matched session.  */
3859             *session_index = i;
3860             *client_session_ptr = &(pppoe_server_ptr -> nx_pppoe_client_session[i]);
3861 
3862             return(NX_PPPOE_SERVER_SUCCESS);
3863         }
3864         else
3865         {
3866 
3867             /* Set the first available index.  */
3868             if (i < available_index)
3869                 available_index = i;
3870         }
3871     }
3872 
3873     /* If the session id is not zero, means the session has been established.  */
3874     if (session_id != 0)
3875     {
3876         return(NX_PPPOE_SERVER_CLIENT_SESSION_NOT_FOUND);
3877     }
3878 
3879     /* Check if there is available room in the table for a new client session. */
3880     if (available_index >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
3881     {
3882 
3883         /* No, we cannot add this client session into the server's table. */
3884         return(NX_PPPOE_SERVER_CLIENT_SESSION_FULL);
3885     }
3886 
3887     /* Set the session.  */
3888     pppoe_server_ptr -> nx_pppoe_client_session[available_index].nx_pppoe_physical_address_msw = client_mac_msw;
3889     pppoe_server_ptr -> nx_pppoe_client_session[available_index].nx_pppoe_physical_address_lsw = client_mac_lsw;
3890 
3891     /* Mark this session is valid.  */
3892     pppoe_server_ptr -> nx_pppoe_client_session[available_index].nx_pppoe_valid = NX_TRUE;
3893 
3894     /* Set local pointer to an available slot. */
3895     *session_index = available_index;
3896     *client_session_ptr = &(pppoe_server_ptr -> nx_pppoe_client_session[available_index]);
3897 
3898     /* Return success.  */
3899     return(NX_PPPOE_SERVER_SUCCESS);
3900 }
3901 
3902 
3903 /**************************************************************************/
3904 /*                                                                        */
3905 /*  FUNCTION                                               RELEASE        */
3906 /*                                                                        */
3907 /*    _nx_pppoe_server_session_cleanup                    PORTABLE C      */
3908 /*                                                           6.1          */
3909 /*  AUTHOR                                                                */
3910 /*                                                                        */
3911 /*    Yuxin Zhou, Microsoft Corporation                                   */
3912 /*                                                                        */
3913 /*  DESCRIPTION                                                           */
3914 /*                                                                        */
3915 /*    This function cleans up the PPPoE session.                          */
3916 /*                                                                        */
3917 /*  INPUT                                                                 */
3918 /*                                                                        */
3919 /*    client_session_ptr                    Pointer to Client Session     */
3920 /*                                                                        */
3921 /*  OUTPUT                                                                */
3922 /*                                                                        */
3923 /*    status                                Completion status             */
3924 /*                                                                        */
3925 /*  CALLS                                                                 */
3926 /*                                                                        */
3927 /*    None                                                                */
3928 /*                                                                        */
3929 /*  CALLED BY                                                             */
3930 /*                                                                        */
3931 /*    _nx_pppoe_server_session_terminate    Terminate the PPPoE session   */
3932 /*    _nx_pppoe_server_session_packet_process                             */
3933 /*                                          Process PPPoE Session packet  */
3934 /*                                                                        */
3935 /*  RELEASE HISTORY                                                       */
3936 /*                                                                        */
3937 /*    DATE              NAME                      DESCRIPTION             */
3938 /*                                                                        */
3939 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
3940 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
3941 /*                                            resulting in version 6.1    */
3942 /*                                                                        */
3943 /**************************************************************************/
_nx_pppoe_server_session_cleanup(NX_PPPOE_CLIENT_SESSION * client_session_ptr)3944 static UINT  _nx_pppoe_server_session_cleanup(NX_PPPOE_CLIENT_SESSION *client_session_ptr)
3945 {
3946 
3947 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
3948 NX_PACKET   *next_packet;
3949 NX_PACKET   *current_packet;
3950 #endif
3951 
3952     /* Cleanup the client session.  */
3953     client_session_ptr -> nx_pppoe_valid = NX_FALSE;
3954     client_session_ptr -> nx_pppoe_session_id = NX_NULL;
3955     client_session_ptr -> nx_pppoe_physical_address_msw = NX_NULL;
3956     client_session_ptr -> nx_pppoe_physical_address_lsw = NX_NULL;
3957     client_session_ptr -> nx_pppoe_service_name = NX_NULL;
3958 
3959 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
3960     /* Loop to release the queued packet.  */
3961     next_packet = client_session_ptr -> nx_pppoe_deferred_received_packet_head;
3962 
3963     /* Release any packets queued up.  */
3964     while (next_packet)
3965     {
3966 
3967         /* Setup the current packet pointer.  */
3968         current_packet = next_packet;
3969 
3970         /* Move to the next packet.  */
3971         next_packet =  next_packet -> nx_packet_queue_next;
3972 
3973         /* Release the current packet.  */
3974         nx_packet_release(current_packet);
3975     }
3976 
3977     /* Cleanup the parameters.  */
3978     client_session_ptr -> nx_pppoe_deferred_received_packet_head = NX_NULL;
3979     client_session_ptr -> nx_pppoe_deferred_received_packet_tail = NX_NULL;
3980     client_session_ptr -> nx_pppoe_packet_receive_stopped = NX_FALSE;
3981 #endif
3982 
3983     /* Return success.  */
3984     return(NX_PPPOE_SERVER_SUCCESS);
3985 }
3986 
3987 
3988 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
3989 /**************************************************************************/
3990 /*                                                                        */
3991 /*  FUNCTION                                               RELEASE        */
3992 /*                                                                        */
3993 /*    PppInitInd                                          PORTABLE C      */
3994 /*                                                           6.1.4        */
3995 /*  AUTHOR                                                                */
3996 /*                                                                        */
3997 /*    Yuxin Zhou, Microsoft Corporation                                   */
3998 /*                                                                        */
3999 /*  DESCRIPTION                                                           */
4000 /*                                                                        */
4001 /*    This function configures the default Service Namet that the PPPoE   */
4002 /*    should use to filter incoming PADI requests.                        */
4003 /*                                                                        */
4004 /*  INPUT                                                                 */
4005 /*                                                                        */
4006 /*    length                                The number of bytes in aData  */
4007 /*    aData                                 Contains PPPoE Service Name   */
4008 /*                                                                        */
4009 /*  OUTPUT                                                                */
4010 /*                                                                        */
4011 /*    None                                                                */
4012 /*                                                                        */
4013 /*  CALLS                                                                 */
4014 /*                                                                        */
4015 /*    _nx_pppoe_server_service_name_set     Set the service name          */
4016 /*                                                                        */
4017 /*  CALLED BY                                                             */
4018 /*                                                                        */
4019 /*    Application                                                         */
4020 /*                                                                        */
4021 /*  RELEASE HISTORY                                                       */
4022 /*                                                                        */
4023 /*    DATE              NAME                      DESCRIPTION             */
4024 /*                                                                        */
4025 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4026 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4027 /*                                            resulting in version 6.1    */
4028 /*  02-02-2021     Yuxin Zhou               Modified comment(s),          */
4029 /*                                            fixed the compiler errors,  */
4030 /*                                            resulting in version 6.1.4  */
4031 /*                                                                        */
4032 /**************************************************************************/
PppInitInd(UINT length,UCHAR * aData)4033 VOID  PppInitInd(UINT length, UCHAR *aData)
4034 {
4035 
4036     /* Check to see if PPPoE instance is created.  */
4037     if ((_nx_pppoe_server_created_ptr == NX_NULL) ||
4038         (_nx_pppoe_server_created_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
4039         return;
4040 
4041     /* Check the length.  */
4042     if (length == 0)
4043     {
4044 
4045         /* Clean the default service name.  */
4046         _nx_pppoe_server_service_name_set(_nx_pppoe_server_created_ptr, NX_NULL, 0);
4047     }
4048     else
4049     {
4050 
4051         /* Transmit the Service.  */
4052         nx_pppoe_service_name[0] = aData;
4053 
4054         /* Set the default service name.  */
4055         _nx_pppoe_server_service_name_set(_nx_pppoe_server_created_ptr, nx_pppoe_service_name, 1);
4056     }
4057 }
4058 
4059 
4060 /**************************************************************************/
4061 /*                                                                        */
4062 /*  FUNCTION                                               RELEASE        */
4063 /*                                                                        */
4064 /*    PppDiscoverCnf                                      PORTABLE C      */
4065 /*                                                           6.1          */
4066 /*  AUTHOR                                                                */
4067 /*                                                                        */
4068 /*    Yuxin Zhou, Microsoft Corporation                                   */
4069 /*                                                                        */
4070 /*  DESCRIPTION                                                           */
4071 /*                                                                        */
4072 /*    This function defines the Service Name field of the PADO packet.    */
4073 /*                                                                        */
4074 /*  INPUT                                                                 */
4075 /*                                                                        */
4076 /*    interfaceHandle                       The handle of session         */
4077 /*    length                                The number of bytes in aData  */
4078 /*    aData                                 Contains PPPoE Service Name   */
4079 /*                                                                        */
4080 /*  OUTPUT                                                                */
4081 /*                                                                        */
4082 /*    None                                                                */
4083 /*                                                                        */
4084 /*  CALLS                                                                 */
4085 /*                                                                        */
4086 /*    tx_mutex_get                          Obtain a protection mutex     */
4087 /*    tx_mutex_put                          Release protection mutex      */
4088 /*    _nx_pppoe_server_discovery_send       Send PPPoE Discovery          */
4089 /*                                                                        */
4090 /*  CALLED BY                                                             */
4091 /*                                                                        */
4092 /*    Application                                                         */
4093 /*                                                                        */
4094 /*  RELEASE HISTORY                                                       */
4095 /*                                                                        */
4096 /*    DATE              NAME                      DESCRIPTION             */
4097 /*                                                                        */
4098 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4099 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4100 /*                                            resulting in version 6.1    */
4101 /*                                                                        */
4102 /**************************************************************************/
PppDiscoverCnf(UINT length,UCHAR * aData,UINT interfaceHandle)4103 VOID PppDiscoverCnf(UINT length, UCHAR *aData, UINT interfaceHandle)
4104 {
4105 
4106 NX_PPPOE_CLIENT_SESSION *client_session_ptr;
4107 
4108     /* Check to see if PPPoE instance is created.  */
4109     if ((_nx_pppoe_server_created_ptr == NX_NULL) ||
4110         (_nx_pppoe_server_created_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
4111         return;
4112 
4113     /* Check to see if PPPoE is enabled.  */
4114     if (_nx_pppoe_server_created_ptr -> nx_pppoe_enabled != NX_TRUE)
4115         return;
4116 
4117     /* Check for invalid session index.  */
4118     if(interfaceHandle >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
4119         return;
4120 
4121     /* Check to see if PPPoE session is valid.  */
4122     if (_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_valid != NX_TRUE)
4123         return;
4124 
4125     /* Obtain the IP internal mutex before processing the IP event.  */
4126     tx_mutex_get(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
4127 
4128     /* Get the Session pointer.  */
4129     client_session_ptr = &(_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle]);
4130 
4131     /* Check if this session is valid.  */
4132     if (client_session_ptr -> nx_pppoe_valid != NX_TRUE)
4133     {
4134 
4135         /* Release the IP internal mutex.  */
4136         tx_mutex_put(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
4137 
4138         return;
4139     }
4140 
4141     /* Set the Service Name field.  */
4142     client_session_ptr -> nx_pppoe_service_name = aData;
4143     client_session_ptr -> nx_pppoe_service_name_length = length;
4144 
4145     /* Send PADO packet.  */
4146     _nx_pppoe_server_discovery_send(_nx_pppoe_server_created_ptr, client_session_ptr, NX_PPPOE_SERVER_CODE_PADO);
4147 
4148     /* Release the IP internal mutex.  */
4149     tx_mutex_put(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
4150 
4151     return;
4152 }
4153 
4154 
4155 /**************************************************************************/
4156 /*                                                                        */
4157 /*  FUNCTION                                               RELEASE        */
4158 /*                                                                        */
4159 /*    PppOpenCnf                                          PORTABLE C      */
4160 /*                                                           6.1          */
4161 /*  AUTHOR                                                                */
4162 /*                                                                        */
4163 /*    Yuxin Zhou, Microsoft Corporation                                   */
4164 /*                                                                        */
4165 /*  DESCRIPTION                                                           */
4166 /*                                                                        */
4167 /*    This function allows PPPoE to accept or reject the PPPoE Session.   */
4168 /*                                                                        */
4169 /*  INPUT                                                                 */
4170 /*                                                                        */
4171 /*    accept                                The flag to accept or reject  */
4172 /*    interfaceHandle                       The handle of session         */
4173 /*                                                                        */
4174 /*  OUTPUT                                                                */
4175 /*                                                                        */
4176 /*    None                                                                */
4177 /*                                                                        */
4178 /*  CALLS                                                                 */
4179 /*                                                                        */
4180 /*    tx_mutex_get                          Obtain a protection mutex     */
4181 /*    tx_mutex_put                          Release protection mutex      */
4182 /*    _nx_pppoe_server_discovery_send       Send PPPoE Discovery          */
4183 /*    _nx_pppoe_server_session_cleanup      Cleanup the PPPoE Session     */
4184 /*                                                                        */
4185 /*  CALLED BY                                                             */
4186 /*                                                                        */
4187 /*    Application                                                         */
4188 /*                                                                        */
4189 /*  RELEASE HISTORY                                                       */
4190 /*                                                                        */
4191 /*    DATE              NAME                      DESCRIPTION             */
4192 /*                                                                        */
4193 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4194 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4195 /*                                            resulting in version 6.1    */
4196 /*                                                                        */
4197 /**************************************************************************/
PppOpenCnf(UCHAR accept,UINT interfaceHandle)4198 VOID PppOpenCnf(UCHAR accept, UINT interfaceHandle)
4199 {
4200 
4201 NX_PPPOE_CLIENT_SESSION *client_session_ptr;
4202 
4203     /* Check to see if PPPoE instance is created.  */
4204     if ((_nx_pppoe_server_created_ptr == NX_NULL) ||
4205         (_nx_pppoe_server_created_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
4206         return;
4207 
4208     /* Check to see if PPPoE is enabled.  */
4209     if (_nx_pppoe_server_created_ptr -> nx_pppoe_enabled != NX_TRUE)
4210         return;
4211 
4212     /* Check for invalid session index.  */
4213     if(interfaceHandle >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
4214         return;
4215 
4216     /* Check to see if PPPoE session is valid.  */
4217     if (_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_valid != NX_TRUE)
4218         return;
4219 
4220     /* Obtain the IP internal mutex before processing the IP event.  */
4221     tx_mutex_get(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
4222 
4223     /* Get the Session pointer.  */
4224     client_session_ptr = &(_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle]);
4225 
4226     /* Check the accept flag.  */
4227     if (accept == NX_TRUE)
4228     {
4229 
4230         /* Send PADS to accept the PPPoE Session.  */
4231         _nx_pppoe_server_discovery_send(_nx_pppoe_server_created_ptr, client_session_ptr, NX_PPPOE_SERVER_CODE_PADS);
4232     }
4233     else
4234     {
4235 
4236         /* Reject the PPPoE Session.  */
4237         _nx_pppoe_server_session_cleanup(client_session_ptr);
4238     }
4239 
4240     /* Release the IP internal mutex.  */
4241     tx_mutex_put(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
4242 
4243     return;
4244 }
4245 
4246 
4247 /**************************************************************************/
4248 /*                                                                        */
4249 /*  FUNCTION                                               RELEASE        */
4250 /*                                                                        */
4251 /*    PppCloseInd                                         PORTABLE C      */
4252 /*                                                           6.1.4        */
4253 /*  AUTHOR                                                                */
4254 /*                                                                        */
4255 /*    Yuxin Zhou, Microsoft Corporation                                   */
4256 /*                                                                        */
4257 /*  DESCRIPTION                                                           */
4258 /*                                                                        */
4259 /*    This function allows PPPoE to terminate PPPoE Session.              */
4260 /*                                                                        */
4261 /*  INPUT                                                                 */
4262 /*                                                                        */
4263 /*    interfaceHandle                       The handle of session         */
4264 /*    causeCode                             The reason for terminating    */
4265 /*                                                                        */
4266 /*  OUTPUT                                                                */
4267 /*                                                                        */
4268 /*    None                                                                */
4269 /*                                                                        */
4270 /*  CALLS                                                                 */
4271 /*                                                                        */
4272 /*    _nx_pppoe_server_session_terminate    Terminate the PPPoE Session   */
4273 /*                                                                        */
4274 /*  CALLED BY                                                             */
4275 /*                                                                        */
4276 /*    Application                                                         */
4277 /*                                                                        */
4278 /*  RELEASE HISTORY                                                       */
4279 /*                                                                        */
4280 /*    DATE              NAME                      DESCRIPTION             */
4281 /*                                                                        */
4282 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4283 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4284 /*                                            resulting in version 6.1    */
4285 /*  02-02-2021     Yuxin Zhou               Modified comment(s),          */
4286 /*                                            fixed the compiler errors,  */
4287 /*                                            resulting in version 6.1.4  */
4288 /*                                                                        */
4289 /**************************************************************************/
PppCloseInd(UINT interfaceHandle,UCHAR * causeCode)4290 VOID PppCloseInd(UINT interfaceHandle, UCHAR *causeCode)
4291 {
4292 
4293     /* Check to see if PPPoE instance is created.  */
4294     if ((_nx_pppoe_server_created_ptr == NX_NULL) ||
4295         (_nx_pppoe_server_created_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
4296         return;
4297 
4298     /* Check to see if PPPoE is enabled.  */
4299     if (_nx_pppoe_server_created_ptr -> nx_pppoe_enabled != NX_TRUE)
4300         return;
4301 
4302     /* Check for invalid session index.  */
4303     if(interfaceHandle >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
4304         return;
4305 
4306     /* Check to see if PPPoE session is established.  */
4307     if ((_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_valid != NX_TRUE) ||
4308         (_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_session_id == 0))
4309         return;
4310 
4311     /* Obtain the IP internal mutex before processing the IP event.  */
4312     tx_mutex_get(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
4313 
4314     /* Set the reason for terminating the session.  */
4315     _nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_generic_error = causeCode;
4316 
4317     /* Send PADT to terminate the session.  */
4318     _nx_pppoe_server_session_terminate(_nx_pppoe_server_created_ptr, interfaceHandle);
4319 
4320     /* Release the IP internal mutex.  */
4321     tx_mutex_put(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
4322 
4323     return;
4324 }
4325 
4326 
4327 /**************************************************************************/
4328 /*                                                                        */
4329 /*  FUNCTION                                               RELEASE        */
4330 /*                                                                        */
4331 /*    PppCloseCnf                                         PORTABLE C      */
4332 /*                                                           6.1          */
4333 /*  AUTHOR                                                                */
4334 /*                                                                        */
4335 /*    Yuxin Zhou, Microsoft Corporation                                   */
4336 /*                                                                        */
4337 /*  DESCRIPTION                                                           */
4338 /*                                                                        */
4339 /*    This function confirm that the session has been freed.              */
4340 /*                                                                        */
4341 /*  INPUT                                                                 */
4342 /*                                                                        */
4343 /*    interfaceHandle                       The handle of session         */
4344 /*                                                                        */
4345 /*  OUTPUT                                                                */
4346 /*                                                                        */
4347 /*    None                                                                */
4348 /*                                                                        */
4349 /*  CALLS                                                                 */
4350 /*                                                                        */
4351 /*    None                                                                */
4352 /*                                                                        */
4353 /*  CALLED BY                                                             */
4354 /*                                                                        */
4355 /*    Application                                                         */
4356 /*                                                                        */
4357 /*  RELEASE HISTORY                                                       */
4358 /*                                                                        */
4359 /*    DATE              NAME                      DESCRIPTION             */
4360 /*                                                                        */
4361 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4362 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4363 /*                                            resulting in version 6.1    */
4364 /*                                                                        */
4365 /**************************************************************************/
PppCloseCnf(UINT interfaceHandle)4366 VOID PppCloseCnf(UINT interfaceHandle)
4367 {
4368 
4369     /* Check to see if PPPoE instance is created.  */
4370     if ((_nx_pppoe_server_created_ptr == NX_NULL) ||
4371         (_nx_pppoe_server_created_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
4372         return;
4373 
4374     /* Check for invalid session index.  */
4375     if (interfaceHandle >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
4376         return;
4377 
4378     /* Obtain the IP internal mutex before processing the IP event.  */
4379     tx_mutex_get(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
4380 
4381     /* Cleanup the PPPoE session.  */
4382     _nx_pppoe_server_session_cleanup(&(_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle]));
4383 
4384     /* Release the IP internal mutex.  */
4385     tx_mutex_put(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
4386 }
4387 
4388 
4389 /**************************************************************************/
4390 /*                                                                        */
4391 /*  FUNCTION                                               RELEASE        */
4392 /*                                                                        */
4393 /*    PppTransmitDataCnf                                  PORTABLE C      */
4394 /*                                                           6.1.4        */
4395 /*  AUTHOR                                                                */
4396 /*                                                                        */
4397 /*    Yuxin Zhou, Microsoft Corporation                                   */
4398 /*                                                                        */
4399 /*  DESCRIPTION                                                           */
4400 /*                                                                        */
4401 /*    This function allows TTP's software to receive new data frame.      */
4402 /*                                                                        */
4403 /*  INPUT                                                                 */
4404 /*                                                                        */
4405 /*    interfaceHandle                       The handle of session         */
4406 /*                                                                        */
4407 /*  OUTPUT                                                                */
4408 /*                                                                        */
4409 /*    None                                                                */
4410 /*                                                                        */
4411 /*  CALLS                                                                 */
4412 /*                                                                        */
4413 /*    tx_mutex_get                          Obtain a protection mutex     */
4414 /*    tx_mutex_put                          Release protection mutex      */
4415 /*    tx_event_flags_set                    Set events for PPPoE thread   */
4416 /*                                                                        */
4417 /*  CALLED BY                                                             */
4418 /*                                                                        */
4419 /*    Application                                                         */
4420 /*                                                                        */
4421 /*  RELEASE HISTORY                                                       */
4422 /*                                                                        */
4423 /*    DATE              NAME                      DESCRIPTION             */
4424 /*                                                                        */
4425 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4426 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4427 /*                                            resulting in version 6.1    */
4428 /*  02-02-2021     Yuxin Zhou               Modified comment(s),          */
4429 /*                                            fixed the compiler errors,  */
4430 /*                                            resulting in version 6.1.4  */
4431 /*                                                                        */
4432 /**************************************************************************/
PppTransmitDataCnf(UINT interfaceHandle,UCHAR * data_ptr,UINT packet_id)4433 VOID PppTransmitDataCnf(UINT interfaceHandle, UCHAR *data_ptr, UINT packet_id)
4434 {
4435 
4436 NX_PACKET   *packet_ptr;
4437 
4438     NX_PARAMETER_NOT_USED(data_ptr);
4439 
4440     /* Check to see if PPPoE instance is created.  */
4441     if ((_nx_pppoe_server_created_ptr == NX_NULL) ||
4442         (_nx_pppoe_server_created_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
4443         return;
4444 
4445     /* Check for invalid session index.  */
4446     if(interfaceHandle >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
4447         return;
4448 
4449     /* Obtain the IP internal mutex before processing the IP event.  */
4450     tx_mutex_get(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
4451 
4452     /* Release the packet.  */
4453     if (packet_id)
4454     {
4455         packet_ptr = (NX_PACKET *)(packet_id);
4456         nx_packet_release(packet_ptr);
4457     }
4458 
4459     /* Clean the flag to receive the next packet.  */
4460     _nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_packet_receive_stopped = NX_FALSE;
4461 
4462     /* Check if this session queued the packets.  */
4463     if (_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_deferred_received_packet_head)
4464     {
4465 
4466         /* Wakeup PPPoE helper thread to process the PPPoE Session receive.  */
4467         tx_event_flags_set(&(_nx_pppoe_server_created_ptr -> nx_pppoe_events), NX_PPPOE_SERVER_SESSION_RECEIVE_EVENT, TX_OR);
4468     }
4469 
4470     /* Release the IP internal mutex.  */
4471     tx_mutex_put(&(_nx_pppoe_server_created_ptr -> nx_pppoe_ip_ptr -> nx_ip_protection));
4472 }
4473 
4474 
4475 /**************************************************************************/
4476 /*                                                                        */
4477 /*  FUNCTION                                               RELEASE        */
4478 /*                                                                        */
4479 /*    PppReceiveDataInd                                   PORTABLE C      */
4480 /*                                                           6.1.4        */
4481 /*  AUTHOR                                                                */
4482 /*                                                                        */
4483 /*    Yuxin Zhou, Microsoft Corporation                                   */
4484 /*                                                                        */
4485 /*  DESCRIPTION                                                           */
4486 /*                                                                        */
4487 /*    This function sends data fram over Ethernet.                        */
4488 /*                                                                        */
4489 /*  INPUT                                                                 */
4490 /*                                                                        */
4491 /*    interfaceHandle                       The handle of session         */
4492 /*                                                                        */
4493 /*  OUTPUT                                                                */
4494 /*                                                                        */
4495 /*    None                                                                */
4496 /*                                                                        */
4497 /*  CALLS                                                                 */
4498 /*                                                                        */
4499 /*    _nx_pppoe_server_session_send         Send PPPoE session data       */
4500 /*                                                                        */
4501 /*  CALLED BY                                                             */
4502 /*                                                                        */
4503 /*    Application                                                         */
4504 /*                                                                        */
4505 /*  RELEASE HISTORY                                                       */
4506 /*                                                                        */
4507 /*    DATE              NAME                      DESCRIPTION             */
4508 /*                                                                        */
4509 /*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
4510 /*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
4511 /*                                            resulting in version 6.1    */
4512 /*  02-02-2021     Yuxin Zhou               Modified comment(s),          */
4513 /*                                            fixed the compiler errors,  */
4514 /*                                            resulting in version 6.1.4  */
4515 /*                                                                        */
4516 /**************************************************************************/
PppReceiveDataInd(UINT interfaceHandle,UINT data_length,UCHAR * data_ptr)4517 VOID PppReceiveDataInd(UINT interfaceHandle, UINT data_length, UCHAR *data_ptr)
4518 {
4519 
4520     /* Check for invalid input pointers.  */
4521     if ((_nx_pppoe_server_created_ptr == NX_NULL) ||
4522         (_nx_pppoe_server_created_ptr -> nx_pppoe_id != NX_PPPOE_SERVER_ID))
4523         return;
4524 
4525     /* Check to see if PPPoE is enabled.  */
4526     if (_nx_pppoe_server_created_ptr -> nx_pppoe_enabled != NX_TRUE)
4527         return;
4528 
4529     /* Check for invalid session index.  */
4530     if(interfaceHandle >= NX_PPPOE_SERVER_MAX_CLIENT_SESSION_NUMBER)
4531         return;
4532 
4533     /* Check to see if PPPoE session is established.  */
4534     if ((_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_valid != NX_TRUE) ||
4535         (_nx_pppoe_server_created_ptr -> nx_pppoe_client_session[interfaceHandle].nx_pppoe_session_id == 0))
4536         return;
4537 
4538     /* Send data.  */
4539     _nx_pppoe_server_session_send(_nx_pppoe_server_created_ptr, interfaceHandle, data_ptr, data_length);
4540 }
4541 #endif
4542 #endif /* NX_DISABLE_IPV4 */
4543