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