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