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