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