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