TianoCore EDK2 master
Loading...
Searching...
No Matches
Dhcp6Utility.c
Go to the documentation of this file.
1
11#include "Dhcp6Impl.h"
12
13//
14// Verifies the packet cursor is within the packet
15// otherwise it is invalid
16//
17#define IS_INVALID_PACKET_CURSOR(PacketCursor, Packet) \
18 (((*PacketCursor) < (Packet)->Dhcp6.Option) || \
19 ((*PacketCursor) >= (Packet)->Dhcp6.Option + ((Packet)->Size - sizeof(EFI_DHCP6_HEADER))) \
20 ) \
21
22
35 )
36{
37 EFI_STATUS Status;
38 EFI_DHCP6_DUID *Duid;
39 EFI_TIME Time;
40 UINT32 Stamp;
41 EFI_GUID Uuid;
42
43 //
44 // Attempt to get client Id from variable to keep it constant.
45 // See details in section-9 of rfc-3315.
46 //
47 GetVariable2 (L"ClientId", &gEfiDhcp6ServiceBindingProtocolGuid, (VOID **)&Duid, NULL);
48 if (Duid != NULL) {
49 return Duid;
50 }
51
52 //
53 // The format of client identifier option:
54 //
55 // 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
56 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 // | OPTION_CLIENTID | option-len |
58 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 // . .
60 // . DUID .
61 // . (variable length) .
62 // . .
63 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 //
65
66 //
67 // If System UUID is found from SMBIOS Table, use DUID-UUID type.
68 //
69 if ((PcdGet8 (PcdDhcp6UidType) == Dhcp6DuidTypeUuid) && !EFI_ERROR (NetLibGetSystemGuid (&Uuid)) && !CompareGuid (&Uuid, &gZeroGuid)) {
70 //
71 //
72 // The format of DUID-UUID:
73 //
74 // 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
75 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76 // | DUID-Type (4) | UUID (128 bits) |
77 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
78 // | |
79 // | |
80 // | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81 // | |
82 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
83
84 //
85 // sizeof (option-len + Duid-type + UUID-size) = 20 bytes
86 //
87 Duid = AllocateZeroPool (2 + 2 + sizeof (EFI_GUID));
88 if (Duid == NULL) {
89 return NULL;
90 }
91
92 //
93 // sizeof (Duid-type + UUID-size) = 18 bytes
94 //
95 Duid->Length = (UINT16)(18);
96
97 //
98 // Set the Duid-type and copy UUID.
99 //
100 WriteUnaligned16 ((UINT16 *)(Duid->Duid), HTONS (Dhcp6DuidTypeUuid));
101
102 CopyMem (Duid->Duid + 2, &Uuid, sizeof (EFI_GUID));
103 } else {
104 //
105 //
106 // The format of DUID-LLT:
107 //
108 // 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
109 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
110 // | Duid type (1) | hardware type (16 bits) |
111 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
112 // | time (32 bits) |
113 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
114 // . .
115 // . link-layer address (variable length) .
116 // . .
117 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118 //
119
120 //
121 // Generate a time stamp of the seconds from 2000/1/1, assume 30day/month.
122 //
123 gRT->GetTime (&Time, NULL);
124 Stamp = (UINT32)
125 (
126 ((((UINT32)(Time.Year - 2000) * 360 + (Time.Month - 1) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) *
127 60 +
128 Time.Second
129 );
130
131 //
132 // sizeof (option-len + Duid-type + hardware-type + time) = 10 bytes
133 //
134 Duid = AllocateZeroPool (10 + Mode->HwAddressSize);
135 if (Duid == NULL) {
136 return NULL;
137 }
138
139 //
140 // sizeof (Duid-type + hardware-type + time) = 8 bytes
141 //
142 Duid->Length = (UINT16)(Mode->HwAddressSize + 8);
143
144 //
145 // Set the Duid-type, hardware-type, time and copy the hardware address.
146 //
147 WriteUnaligned16 ((UINT16 *)((UINT8 *)Duid + OFFSET_OF (EFI_DHCP6_DUID, Duid)), HTONS (Dhcp6DuidTypeLlt));
148 WriteUnaligned16 ((UINT16 *)((UINT8 *)Duid + OFFSET_OF (EFI_DHCP6_DUID, Duid) + 2), HTONS (NET_IFTYPE_ETHERNET));
149 WriteUnaligned32 ((UINT32 *)((UINT8 *)Duid + OFFSET_OF (EFI_DHCP6_DUID, Duid) + 4), HTONL (Stamp));
150
151 CopyMem (Duid->Duid + 8, &Mode->CurrentAddress, Mode->HwAddressSize);
152 }
153
154 Status = gRT->SetVariable (
155 L"ClientId",
156 &gEfiDhcp6ServiceBindingProtocolGuid,
157 (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS),
158 Duid->Length + 2,
159 (VOID *)Duid
160 );
161 if (EFI_ERROR (Status)) {
162 FreePool (Duid);
163 return NULL;
164 }
165
166 return Duid;
167}
168
183 )
184{
185 UINTN Index;
186 UINTN OptionListSize;
187 UINTN OptionSize;
188
189 CopyMem (DstCfg, SorCfg, sizeof (EFI_DHCP6_CONFIG_DATA));
190
191 //
192 // Allocate another buffer for solicitretransmission, and copy it.
193 //
194 if (SorCfg->SolicitRetransmission != NULL) {
195 DstCfg->SolicitRetransmission = AllocateZeroPool (sizeof (EFI_DHCP6_RETRANSMISSION));
196
197 if (DstCfg->SolicitRetransmission == NULL) {
198 //
199 // Error will be handled out of this function.
200 //
201 return EFI_OUT_OF_RESOURCES;
202 }
203
204 CopyMem (
205 DstCfg->SolicitRetransmission,
206 SorCfg->SolicitRetransmission,
208 );
209 }
210
211 if ((SorCfg->OptionList != NULL) && (SorCfg->OptionCount != 0)) {
212 OptionListSize = SorCfg->OptionCount * sizeof (EFI_DHCP6_PACKET_OPTION *);
213 DstCfg->OptionList = AllocateZeroPool (OptionListSize);
214
215 if (DstCfg->OptionList == NULL) {
216 //
217 // Error will be handled out of this function.
218 //
219 return EFI_OUT_OF_RESOURCES;
220 }
221
222 for (Index = 0; Index < SorCfg->OptionCount; Index++) {
223 OptionSize = NTOHS (SorCfg->OptionList[Index]->OpLen) + 4;
224 DstCfg->OptionList[Index] = AllocateZeroPool (OptionSize);
225
226 if (DstCfg->OptionList[Index] == NULL) {
227 //
228 // Error will be handled out of this function.
229 //
230 return EFI_OUT_OF_RESOURCES;
231 }
232
233 CopyMem (
234 DstCfg->OptionList[Index],
235 SorCfg->OptionList[Index],
236 OptionSize
237 );
238 }
239 }
240
241 return EFI_SUCCESS;
242}
243
250VOID
253 )
254{
255 UINTN Index;
256
257 ASSERT (CfgData != NULL);
258 //
259 // Clean up all fields in config data including the reference buffers, but do
260 // not free the config data buffer itself.
261 //
262 if (CfgData->OptionList != NULL) {
263 for (Index = 0; Index < CfgData->OptionCount; Index++) {
264 if (CfgData->OptionList[Index] != NULL) {
265 FreePool (CfgData->OptionList[Index]);
266 }
267 }
268
269 FreePool (CfgData->OptionList);
270 }
271
272 if (CfgData->SolicitRetransmission != NULL) {
273 FreePool (CfgData->SolicitRetransmission);
274 }
275
276 ZeroMem (CfgData, sizeof (EFI_DHCP6_CONFIG_DATA));
277}
278
285VOID
287 IN OUT EFI_DHCP6_MODE_DATA *ModeData
288 )
289{
290 ASSERT (ModeData != NULL);
291 //
292 // Clean up all fields in mode data including the reference buffers, but do
293 // not free the mode data buffer itself.
294 //
295 if (ModeData->ClientId != NULL) {
296 FreePool (ModeData->ClientId);
297 }
298
299 if (ModeData->Ia != NULL) {
300 if (ModeData->Ia->ReplyPacket != NULL) {
301 FreePool (ModeData->Ia->ReplyPacket);
302 }
303
304 FreePool (ModeData->Ia);
305 }
306
307 ZeroMem (ModeData, sizeof (EFI_DHCP6_MODE_DATA));
308}
309
320UINT32
322 IN UINT32 Base,
323 IN BOOLEAN IsFirstRt,
324 IN BOOLEAN NeedSigned
325 )
326{
327 EFI_TIME Time;
328 BOOLEAN Signed;
329 UINT32 Seed;
330 UINT32 Expire;
331
332 //
333 // Take the 10bits of microsecond in system time as a uniform distribution.
334 // Take the 10th bit as a flag to determine it's signed or not.
335 //
336 gRT->GetTime (&Time, NULL);
337 Seed = ((Time.Nanosecond >> 10) & DHCP6_10_BIT_MASK);
338 Signed = (BOOLEAN)((((Time.Nanosecond >> 9) & 0x01) != 0) ? TRUE : FALSE);
339 Signed = (BOOLEAN)(NeedSigned ? Signed : FALSE);
340
341 //
342 // Calculate expire by the following algo:
343 // 1. base + base * (-0.1 ~ 0) for the first solicit
344 // 2. base + base * (-0.1 ~ 0.1) for the first other messages
345 // 3. 2 * base + base * (-0.1 ~ 0.1) for the subsequent all messages
346 // 4. base + base * (-0.1 ~ 0) for the more than mrt timeout
347 //
348 // The (Seed / 0x3ff / 10) is used to a random range (0, 0.1).
349 //
350 if (IsFirstRt && Signed) {
351 Expire = Base - (UINT32)(Base * Seed / DHCP6_10_BIT_MASK / 10);
352 } else if (IsFirstRt && !Signed) {
353 Expire = Base + (UINT32)(Base * Seed / DHCP6_10_BIT_MASK / 10);
354 } else if (!IsFirstRt && Signed) {
355 Expire = 2 * Base - (UINT32)(Base * Seed / DHCP6_10_BIT_MASK / 10);
356 } else {
357 Expire = 2 * Base + (UINT32)(Base * Seed / DHCP6_10_BIT_MASK / 10);
358 }
359
360 Expire = (Expire != 0) ? Expire : 1;
361
362 return Expire;
363}
364
371VOID
373 IN DHCP6_IA_CB *IaCb
374 )
375{
376 UINT32 MinLt;
377 UINT32 MaxLt;
378 UINTN Index;
379
380 ASSERT (IaCb->Ia->IaAddressCount > 0);
381
382 MinLt = (UINT32)(-1);
383 MaxLt = 0;
384
385 //
386 // Calculate minlt as min of all valid life time, and maxlt as max of all
387 // valid life time.
388 //
389 for (Index = 0; Index < IaCb->Ia->IaAddressCount; Index++) {
390 MinLt = MIN (MinLt, IaCb->Ia->IaAddress[Index].ValidLifetime);
391 MaxLt = MAX (MinLt, IaCb->Ia->IaAddress[Index].ValidLifetime);
392 }
393
394 //
395 // Take 50% minlt as t1, and 80% maxlt as t2 if Dhcp6 server doesn't offer
396 // such information.
397 //
398 IaCb->T1 = (IaCb->T1 != 0) ? IaCb->T1 : (UINT32)(MinLt * 5 / 10);
399 IaCb->T2 = (IaCb->T2 != 0) ? IaCb->T2 : (UINT32)(MinLt * 8 / 10);
400 IaCb->AllExpireTime = MaxLt;
401 IaCb->LeaseTime = 0;
402}
403
417 IN EFI_DHCP6_IA *Ia,
418 IN UINT32 AddressCount,
419 IN EFI_IPv6_ADDRESS *Addresses
420 )
421{
422 UINTN Index1;
423 UINTN Index2;
424 BOOLEAN Found;
425
426 //
427 // Check whether the addresses are all included by the configured IA. And it
428 // will return success if address count is zero, which means all addresses.
429 //
430 for (Index1 = 0; Index1 < AddressCount; Index1++) {
431 Found = FALSE;
432
433 for (Index2 = 0; Index2 < Ia->IaAddressCount; Index2++) {
434 if (CompareMem (
435 &Addresses[Index1],
436 &Ia->IaAddress[Index2],
437 sizeof (EFI_IPv6_ADDRESS)
438 ) == 0)
439 {
440 Found = TRUE;
441 break;
442 }
443 }
444
445 if (!Found) {
446 return EFI_NOT_FOUND;
447 }
448 }
449
450 return EFI_SUCCESS;
451}
452
466 IN EFI_DHCP6_IA *Ia,
467 IN UINT32 AddressCount,
468 IN EFI_IPv6_ADDRESS *Addresses
469 )
470{
471 EFI_DHCP6_IA *IaCopy;
472 UINTN IaCopySize;
473 UINTN Index1;
474 UINTN Index2;
475 BOOLEAN Found;
476
477 if (AddressCount == 0) {
478 //
479 // It means release all Ia addresses if address count is zero.
480 //
481 AddressCount = Ia->IaAddressCount;
482 }
483
484 ASSERT (AddressCount != 0);
485
486 IaCopySize = sizeof (EFI_DHCP6_IA) + (AddressCount - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
487 IaCopy = AllocateZeroPool (IaCopySize);
488
489 if (IaCopy == NULL) {
490 return NULL;
491 }
492
493 if (AddressCount == Ia->IaAddressCount) {
494 //
495 // If release all Ia addresses, just copy the configured Ia and then set
496 // its address count as zero.
497 // We may decline/release part of addresses at the beginning. So it's a
498 // forwarding step to update address infor for decline/release, while the
499 // other infor such as Ia state will be updated when receiving reply.
500 //
501 CopyMem (IaCopy, Ia, IaCopySize);
502 Ia->IaAddressCount = 0;
503 return IaCopy;
504 }
505
506 CopyMem (IaCopy, Ia, sizeof (EFI_DHCP6_IA));
507
508 //
509 // Move the addresses from the Ia of instance to the deprived Ia.
510 //
511 for (Index1 = 0; Index1 < AddressCount; Index1++) {
512 Found = FALSE;
513
514 for (Index2 = 0; Index2 < Ia->IaAddressCount; Index2++) {
515 if (CompareMem (
516 &Addresses[Index1],
517 &Ia->IaAddress[Index2],
518 sizeof (EFI_IPv6_ADDRESS)
519 ) == 0)
520 {
521 //
522 // Copy the deprived address to the copy of Ia
523 //
524 CopyMem (
525 &IaCopy->IaAddress[Index1],
526 &Ia->IaAddress[Index2],
527 sizeof (EFI_DHCP6_IA_ADDRESS)
528 );
529 //
530 // Delete the deprived address from the instance Ia
531 //
532 if (Index2 + 1 < Ia->IaAddressCount) {
533 CopyMem (
534 &Ia->IaAddress[Index2],
535 &Ia->IaAddress[Index2 + 1],
536 (Ia->IaAddressCount - Index2 - 1) * sizeof (EFI_DHCP6_IA_ADDRESS)
537 );
538 }
539
540 Found = TRUE;
541 break;
542 }
543 }
544
545 ASSERT (Found == TRUE);
546 }
547
548 Ia->IaAddressCount -= AddressCount;
549 IaCopy->IaAddressCount = AddressCount;
550
551 return IaCopy;
552}
553
560VOID
561EFIAPI
563 IN VOID *Arg
564 )
565{
566}
567
577VOID
578EFIAPI
580 IN NET_BUF *Wrap,
581 IN UDP_END_POINT *EndPoint,
582 IN EFI_STATUS IoStatus,
583 IN VOID *Context
584 )
585{
586 NetbufFree (Wrap);
587}
588
607 IN OUT EFI_DHCP6_PACKET *Packet,
608 IN OUT UINT8 **PacketCursor,
609 IN UINT16 OptType,
610 IN UINT16 OptLen,
611 IN UINT8 *Data
612 )
613{
614 UINT32 Length;
615 UINT32 BytesNeeded;
616
617 //
618 // The format of Dhcp6 option:
619 //
620 // 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
621 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
622 // | option-code | option-len (option data) |
623 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
624 // | option-data |
625 // | (option-len octets) |
626 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
627 //
628
629 //
630 // Verify the arguments are valid
631 //
632 if (Packet == NULL) {
633 return EFI_INVALID_PARAMETER;
634 }
635
636 if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
637 return EFI_INVALID_PARAMETER;
638 }
639
640 if (Data == NULL) {
641 return EFI_INVALID_PARAMETER;
642 }
643
644 if (OptLen == 0) {
645 return EFI_INVALID_PARAMETER;
646 }
647
648 //
649 // Verify the PacketCursor is within the packet
650 //
651 if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) {
652 return EFI_INVALID_PARAMETER;
653 }
654
655 //
656 // Calculate the bytes needed for the option
657 //
658 BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN + NTOHS (OptLen);
659
660 //
661 // Space remaining in the packet
662 //
663 Length = Packet->Size - Packet->Length;
664 if (Length < BytesNeeded) {
665 return EFI_BUFFER_TOO_SMALL;
666 }
667
668 WriteUnaligned16 ((UINT16 *)*PacketCursor, OptType);
669 *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
670 WriteUnaligned16 ((UINT16 *)*PacketCursor, OptLen);
671 *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
672 CopyMem (*PacketCursor, Data, NTOHS (OptLen));
673 *PacketCursor += NTOHS (OptLen);
674
675 // Update the packet length by the length of the option + 4 bytes
676 Packet->Length += BytesNeeded;
677
678 return EFI_SUCCESS;
679}
680
698 IN OUT EFI_DHCP6_PACKET *Packet,
699 IN OUT UINT8 **PacketCursor,
700 IN EFI_DHCP6_IA_ADDRESS *IaAddr,
701 IN UINT32 MessageType
702 )
703{
704 UINT32 BytesNeeded;
705 UINT32 Length;
706
707 // The format of the IA Address option is:
708 //
709 // 0 1 2 3
710 // 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
711 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
712 // | OPTION_IAADDR | option-len |
713 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
714 // | |
715 // | IPv6 address |
716 // | |
717 // | |
718 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
719 // | preferred-lifetime |
720 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
721 // | valid-lifetime |
722 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
723 // . .
724 // . IAaddr-options .
725 // . .
726 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
727
728 //
729 // Verify the arguments are valid
730 //
731 if (Packet == NULL) {
732 return EFI_INVALID_PARAMETER;
733 }
734
735 if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
736 return EFI_INVALID_PARAMETER;
737 }
738
739 if (IaAddr == NULL) {
740 return EFI_INVALID_PARAMETER;
741 }
742
743 //
744 // Verify the PacketCursor is within the packet
745 //
746 if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) {
747 return EFI_INVALID_PARAMETER;
748 }
749
750 BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
751 BytesNeeded += sizeof (EFI_IPv6_ADDRESS);
752 //
753 // Even if the preferred-lifetime is 0, it still needs to store it.
754 //
755 BytesNeeded += sizeof (IaAddr->PreferredLifetime);
756 //
757 // Even if the valid-lifetime is 0, it still needs to store it.
758 //
759 BytesNeeded += sizeof (IaAddr->ValidLifetime);
760
761 //
762 // Space remaining in the packet
763 //
764 Length = Packet->Size - Packet->Length;
765 if (Length < BytesNeeded) {
766 return EFI_BUFFER_TOO_SMALL;
767 }
768
769 //
770 // Fill the value of Ia Address option type
771 //
772 WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptIaAddr));
773 *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
774
775 WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (sizeof (EFI_DHCP6_IA_ADDRESS)));
776 *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
777
778 CopyMem (*PacketCursor, &IaAddr->IpAddress, sizeof (EFI_IPv6_ADDRESS));
779 *PacketCursor += sizeof (EFI_IPv6_ADDRESS);
780
781 //
782 // Fill the value of preferred-lifetime and valid-lifetime.
783 // According to RFC3315 Chapter 18.1.2, the preferred-lifetime and valid-lifetime fields
784 // should set to 0 when initiate a Confirm message.
785 //
786 if (MessageType != Dhcp6MsgConfirm) {
787 WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->PreferredLifetime));
788 }
789
790 *PacketCursor += sizeof (IaAddr->PreferredLifetime);
791
792 if (MessageType != Dhcp6MsgConfirm) {
793 WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (IaAddr->ValidLifetime));
794 }
795
796 *PacketCursor += sizeof (IaAddr->ValidLifetime);
797
798 //
799 // Update the packet length
800 //
801 Packet->Length += BytesNeeded;
802
803 return EFI_SUCCESS;
804}
805
825 IN OUT EFI_DHCP6_PACKET *Packet,
826 IN OUT UINT8 **PacketCursor,
827 IN EFI_DHCP6_IA *Ia,
828 IN UINT32 T1,
829 IN UINT32 T2,
830 IN UINT32 MessageType
831 )
832{
833 UINT8 *AddrOpt;
834 UINT16 *Len;
835 UINTN Index;
836 UINT32 BytesNeeded;
837 UINT32 Length;
838 EFI_STATUS Status;
839
840 //
841 // The format of IA_NA and IA_TA option:
842 //
843 // 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
844 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
845 // | OPTION_IA_NA | option-len |
846 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
847 // | IAID (4 octets) |
848 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
849 // | T1 (only for IA_NA) |
850 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
851 // | T2 (only for IA_NA) |
852 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
853 // | |
854 // . IA_NA-options/IA_TA-options .
855 // . .
856 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
857 //
858
859 //
860 // Verify the arguments are valid
861 //
862 if (Packet == NULL) {
863 return EFI_INVALID_PARAMETER;
864 }
865
866 if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
867 return EFI_INVALID_PARAMETER;
868 }
869
870 if (Ia == NULL) {
871 return EFI_INVALID_PARAMETER;
872 }
873
874 //
875 // Verify the PacketCursor is within the packet
876 //
877 if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) {
878 return EFI_INVALID_PARAMETER;
879 }
880
881 BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
882 BytesNeeded += sizeof (Ia->Descriptor.IaId);
883 //
884 // + N for the IA_NA-options/IA_TA-options
885 // Dhcp6AppendIaAddrOption will need to check the length for each address
886 //
887 if (Ia->Descriptor.Type == Dhcp6OptIana) {
888 BytesNeeded += sizeof (T1) + sizeof (T2);
889 }
890
891 //
892 // Space remaining in the packet
893 //
894 Length = (UINT16)(Packet->Size - Packet->Length);
895 if (Length < BytesNeeded) {
896 return EFI_BUFFER_TOO_SMALL;
897 }
898
899 //
900 // Fill the value of Ia option type
901 //
902 WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Ia->Descriptor.Type));
903 *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
904
905 //
906 // Fill the len of Ia option later, keep the pointer first
907 //
908 Len = (UINT16 *)*PacketCursor;
909 *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
910
911 //
912 // Fill the value of iaid
913 //
914 WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL (Ia->Descriptor.IaId));
915 *PacketCursor += sizeof (Ia->Descriptor.IaId);
916
917 //
918 // Fill the value of t1 and t2 if iana, keep it 0xffffffff if no specified.
919 //
920 if (Ia->Descriptor.Type == Dhcp6OptIana) {
921 WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T1 != 0) ? T1 : 0xffffffff));
922 *PacketCursor += sizeof (T1);
923 WriteUnaligned32 ((UINT32 *)*PacketCursor, HTONL ((T2 != 0) ? T2 : 0xffffffff));
924 *PacketCursor += sizeof (T2);
925 }
926
927 //
928 // Update the packet length
929 //
930 Packet->Length += BytesNeeded;
931
932 //
933 // Fill all the addresses belong to the Ia
934 //
935 for (Index = 0; Index < Ia->IaAddressCount; Index++) {
936 AddrOpt = (UINT8 *)Ia->IaAddress + Index * sizeof (EFI_DHCP6_IA_ADDRESS);
937 Status = Dhcp6AppendIaAddrOption (Packet, PacketCursor, (EFI_DHCP6_IA_ADDRESS *)AddrOpt, MessageType);
938 if (EFI_ERROR (Status)) {
939 return Status;
940 }
941 }
942
943 //
944 // Fill the value of Ia option length
945 //
946 *Len = HTONS ((UINT16)(*PacketCursor - (UINT8 *)Len - 2));
947
948 return EFI_SUCCESS;
949}
950
969 IN OUT EFI_DHCP6_PACKET *Packet,
970 IN OUT UINT8 **PacketCursor,
971 IN DHCP6_INSTANCE *Instance,
972 OUT UINT16 **Elapsed
973 )
974{
975 UINT32 BytesNeeded;
976 UINT32 Length;
977
978 //
979 // The format of elapsed time option:
980 //
981 // 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
982 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
983 // | OPTION_ELAPSED_TIME | option-len |
984 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
985 // | elapsed-time |
986 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
987 //
988
989 //
990 // Verify the arguments are valid
991 //
992 if (Packet == NULL) {
993 return EFI_INVALID_PARAMETER;
994 }
995
996 if ((PacketCursor == NULL) || (*PacketCursor == NULL)) {
997 return EFI_INVALID_PARAMETER;
998 }
999
1000 if (Instance == NULL) {
1001 return EFI_INVALID_PARAMETER;
1002 }
1003
1004 if (Elapsed == NULL) {
1005 return EFI_INVALID_PARAMETER;
1006 }
1007
1008 //
1009 // Verify the PacketCursor is within the packet
1010 //
1011 if (IS_INVALID_PACKET_CURSOR (PacketCursor, Packet)) {
1012 return EFI_INVALID_PARAMETER;
1013 }
1014
1015 BytesNeeded = DHCP6_SIZE_OF_COMBINED_CODE_AND_LEN;
1016 //
1017 // + 2 for elapsed-time
1018 //
1019 BytesNeeded += sizeof (UINT16);
1020 //
1021 // Space remaining in the packet
1022 //
1023 Length = Packet->Size - Packet->Length;
1024 if (Length < BytesNeeded) {
1025 return EFI_BUFFER_TOO_SMALL;
1026 }
1027
1028 //
1029 // Fill the value of elapsed-time option type.
1030 //
1031 WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (Dhcp6OptElapsedTime));
1032 *PacketCursor += DHCP6_SIZE_OF_OPT_CODE;
1033
1034 //
1035 // Fill the len of elapsed-time option, which is fixed.
1036 //
1037 WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (2));
1038 *PacketCursor += DHCP6_SIZE_OF_OPT_LEN;
1039
1040 //
1041 // Fill in elapsed time value with 0 value for now. The actual value is
1042 // filled in later just before the packet is transmitted.
1043 //
1044 WriteUnaligned16 ((UINT16 *)*PacketCursor, HTONS (0));
1045 *Elapsed = (UINT16 *)*PacketCursor;
1046 *PacketCursor += sizeof (UINT16);
1047
1048 Packet->Length += BytesNeeded;
1049
1050 return EFI_SUCCESS;
1051}
1052
1061VOID
1063 IN UINT16 *Elapsed,
1064 IN DHCP6_INSTANCE *Instance
1065 )
1066{
1067 EFI_TIME Time;
1068 UINT64 CurrentStamp;
1069 UINT64 ElapsedTimeValue;
1070
1071 //
1072 // Generate a time stamp of the centiseconds from 2000/1/1, assume 30day/month.
1073 //
1074 gRT->GetTime (&Time, NULL);
1075 CurrentStamp = MultU64x32 (
1076 ((((UINT32)(Time.Year - 2000) * 360 + (Time.Month - 1) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) * 60 + Time.Second,
1077 100
1078 ) +
1079 DivU64x32 (
1080 Time.Nanosecond,
1081 10000000
1082 );
1083
1084 //
1085 // Sentinel value of 0 means that this is the first DHCP packet that we are
1086 // sending and that we need to initialize the value. First DHCP message
1087 // gets 0 elapsed-time. Otherwise, calculate based on StartTime.
1088 //
1089 if (Instance->StartTime == 0) {
1090 ElapsedTimeValue = 0;
1091 Instance->StartTime = CurrentStamp;
1092 } else {
1093 ElapsedTimeValue = CurrentStamp - Instance->StartTime;
1094
1095 //
1096 // If elapsed time cannot fit in two bytes, set it to 0xffff.
1097 //
1098 if (ElapsedTimeValue > 0xffff) {
1099 ElapsedTimeValue = 0xffff;
1100 }
1101 }
1102
1103 WriteUnaligned16 (Elapsed, HTONS ((UINT16)ElapsedTimeValue));
1104}
1105
1117UINT8 *
1119 IN UINT8 *Buf,
1120 IN UINT32 SeekLen,
1121 IN UINT16 OptType
1122 )
1123{
1124 UINT8 *Cursor;
1125 UINT8 *Option;
1126 UINT16 DataLen;
1127 UINT16 OpCode;
1128
1129 Option = NULL;
1130 Cursor = Buf;
1131
1132 //
1133 // The format of Dhcp6 option refers to Dhcp6AppendOption().
1134 //
1135 while (Cursor < Buf + SeekLen) {
1136 OpCode = ReadUnaligned16 ((UINT16 *)Cursor);
1137 if (OpCode == HTONS (OptType)) {
1138 Option = Cursor;
1139 break;
1140 }
1141
1142 DataLen = NTOHS (ReadUnaligned16 ((UINT16 *)(Cursor + 2)));
1143 Cursor += (DataLen + 4);
1144 }
1145
1146 return Option;
1147}
1148
1160UINT8 *
1162 IN UINT8 *Buf,
1163 IN UINT32 SeekLen,
1165 )
1166{
1167 UINT8 *Cursor;
1168 UINT8 *Option;
1169 UINT16 DataLen;
1170 UINT16 OpCode;
1171 UINT32 IaId;
1172
1173 //
1174 // The format of IA_NA and IA_TA option refers to Dhcp6AppendIaOption().
1175 //
1176 Option = NULL;
1177 Cursor = Buf;
1178
1179 while (Cursor < Buf + SeekLen) {
1180 OpCode = ReadUnaligned16 ((UINT16 *)Cursor);
1181 IaId = ReadUnaligned32 ((UINT32 *)(Cursor + 4));
1182 if ((OpCode == HTONS (IaDesc->Type)) && (IaId == HTONL (IaDesc->IaId))) {
1183 Option = Cursor;
1184 break;
1185 }
1186
1187 DataLen = NTOHS (ReadUnaligned16 ((UINT16 *)(Cursor + 2)));
1188 Cursor += (DataLen + 4);
1189 }
1190
1191 return Option;
1192}
1193
1205BOOLEAN
1207 IN EFI_DHCP6_IA_ADDRESS *IaAddr,
1208 IN EFI_DHCP6_IA *CurrentIa
1209 )
1210{
1211 UINT32 Index;
1212
1213 ASSERT (IaAddr != NULL && CurrentIa != NULL);
1214
1215 for (Index = 0; Index < CurrentIa->IaAddressCount; Index++) {
1216 if (EFI_IP6_EQUAL (&IaAddr->IpAddress, &CurrentIa->IaAddress[Index].IpAddress)) {
1217 return TRUE;
1218 }
1219 }
1220
1221 return FALSE;
1222}
1223
1234VOID
1236 IN EFI_DHCP6_IA *CurrentIa,
1237 IN UINT8 *IaInnerOpt,
1238 IN UINT16 IaInnerLen,
1239 OUT UINT32 *AddrNum,
1240 IN OUT EFI_DHCP6_IA_ADDRESS *AddrBuf
1241 )
1242{
1243 UINT8 *Cursor;
1244 UINT16 DataLen;
1245 UINT16 OpCode;
1246 UINT32 ValidLt;
1247 UINT32 PreferredLt;
1248 EFI_DHCP6_IA_ADDRESS *IaAddr;
1249
1250 //
1251 // The format of the IA Address option:
1252 //
1253 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1254 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1255 // | OPTION_IAADDR | option-len |
1256 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1257 // | |
1258 // | IPv6 address |
1259 // | |
1260 // | |
1261 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1262 // | preferred-lifetime |
1263 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1264 // | valid-lifetime |
1265 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1266 // . .
1267 // . IAaddr-options .
1268 // . .
1269 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1270 //
1271
1272 //
1273 // Two usage model:
1274 //
1275 // 1. Pass addrbuf == null, to get the addrnum over the Ia inner options.
1276 // 2. Pass addrbuf != null, to resolve the addresses over the Ia inner
1277 // options to the addrbuf.
1278 //
1279
1280 Cursor = IaInnerOpt;
1281 *AddrNum = 0;
1282
1283 while (Cursor < IaInnerOpt + IaInnerLen) {
1284 //
1285 // Refer to RFC3315 Chapter 18.1.8, we need to update lifetimes for any addresses in the IA option
1286 // that the client already has recorded in the IA, and discard the Ia address option with 0 valid time.
1287 //
1288 OpCode = ReadUnaligned16 ((UINT16 *)Cursor);
1289 PreferredLt = NTOHL (ReadUnaligned32 ((UINT32 *)(Cursor + 20)));
1290 ValidLt = NTOHL (ReadUnaligned32 ((UINT32 *)(Cursor + 24)));
1291 IaAddr = (EFI_DHCP6_IA_ADDRESS *)(Cursor + 4);
1292 if ((OpCode == HTONS (Dhcp6OptIaAddr)) && (ValidLt >= PreferredLt) &&
1293 (Dhcp6AddrIsInCurrentIa (IaAddr, CurrentIa) || (ValidLt != 0)))
1294 {
1295 if (AddrBuf != NULL) {
1296 CopyMem (AddrBuf, IaAddr, sizeof (EFI_DHCP6_IA_ADDRESS));
1297 AddrBuf->PreferredLifetime = PreferredLt;
1298 AddrBuf->ValidLifetime = ValidLt;
1299 AddrBuf = (EFI_DHCP6_IA_ADDRESS *)((UINT8 *)AddrBuf + sizeof (EFI_DHCP6_IA_ADDRESS));
1300 }
1301
1302 (*AddrNum)++;
1303 }
1304
1305 DataLen = NTOHS (ReadUnaligned16 ((UINT16 *)(Cursor + 2)));
1306 Cursor += (DataLen + 4);
1307 }
1308}
1309
1327 IN DHCP6_INSTANCE *Instance,
1328 IN UINT8 *IaInnerOpt,
1329 IN UINT16 IaInnerLen,
1330 IN UINT32 T1,
1331 IN UINT32 T2
1332 )
1333{
1334 UINT32 AddrNum;
1335 UINT32 IaSize;
1336 EFI_DHCP6_IA *Ia;
1337
1338 if (Instance->IaCb.Ia == NULL) {
1339 return EFI_DEVICE_ERROR;
1340 }
1341
1342 //
1343 // Calculate the number of addresses for this Ia, excluding the addresses with
1344 // the value 0 of valid lifetime.
1345 //
1346 Dhcp6ParseAddrOption (Instance->IaCb.Ia, IaInnerOpt, IaInnerLen, &AddrNum, NULL);
1347
1348 if (AddrNum == 0) {
1349 return EFI_NOT_FOUND;
1350 }
1351
1352 //
1353 // Allocate for new IA.
1354 //
1355 IaSize = sizeof (EFI_DHCP6_IA) + (AddrNum - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
1356 Ia = AllocateZeroPool (IaSize);
1357
1358 if (Ia == NULL) {
1359 return EFI_OUT_OF_RESOURCES;
1360 }
1361
1362 //
1363 // Fill up this new IA fields.
1364 //
1365 Ia->State = Instance->IaCb.Ia->State;
1366 Ia->IaAddressCount = AddrNum;
1367 CopyMem (&Ia->Descriptor, &Instance->Config->IaDescriptor, sizeof (EFI_DHCP6_IA_DESCRIPTOR));
1368 Dhcp6ParseAddrOption (Instance->IaCb.Ia, IaInnerOpt, IaInnerLen, &AddrNum, Ia->IaAddress);
1369
1370 //
1371 // Free original IA resource.
1372 //
1373 if (Instance->IaCb.Ia->ReplyPacket != NULL) {
1374 FreePool (Instance->IaCb.Ia->ReplyPacket);
1375 }
1376
1377 FreePool (Instance->IaCb.Ia);
1378
1379 ZeroMem (&Instance->IaCb, sizeof (DHCP6_IA_CB));
1380
1381 //
1382 // Update IaCb to use new IA.
1383 //
1384 Instance->IaCb.Ia = Ia;
1385
1386 //
1387
1388 // Fill in IaCb fields. Such as T1, T2, AllExpireTime and LeaseTime.
1389 //
1390 Instance->IaCb.T1 = T1;
1391 Instance->IaCb.T2 = T2;
1392 Dhcp6CalculateLeaseTime (&Instance->IaCb);
1393
1394 return EFI_SUCCESS;
1395}
1396
1408 IN DHCP6_INSTANCE *Instance
1409 )
1410{
1411 UINTN IaSize;
1412 EFI_DHCP6_IA *Ia;
1413
1414 Ia = Instance->IaCb.Ia;
1415
1416 if ((Instance->CacheIa == NULL) && (Ia != NULL)) {
1417 //
1418 // Cache the current IA.
1419 //
1420 IaSize = sizeof (EFI_DHCP6_IA) + (Ia->IaAddressCount - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
1421
1422 Instance->CacheIa = AllocateZeroPool (IaSize);
1423 if (Instance->CacheIa == NULL) {
1424 return EFI_OUT_OF_RESOURCES;
1425 }
1426
1427 CopyMem (Instance->CacheIa, Ia, IaSize);
1428 }
1429
1430 return EFI_SUCCESS;
1431}
1432
1439VOID
1441 IN DHCP6_INSTANCE *Instance
1442 )
1443{
1444 UINT8 *Ptr;
1445 UINTN Index;
1446 UINTN IaSize;
1447 UINTN NewIaSize;
1448 EFI_DHCP6_IA *Ia;
1449 EFI_DHCP6_IA *NewIa;
1450 EFI_DHCP6_IA *CacheIa;
1451
1452 Ia = Instance->IaCb.Ia;
1453 CacheIa = Instance->CacheIa;
1454
1455 if ((CacheIa != NULL) && (CacheIa->IaAddressCount != 0)) {
1456 //
1457 // There are old addresses existing. Merge with current addresses.
1458 //
1459 NewIaSize = sizeof (EFI_DHCP6_IA) + (Ia->IaAddressCount + CacheIa->IaAddressCount - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
1460 NewIa = AllocateZeroPool (NewIaSize);
1461 if (NewIa == NULL) {
1462 return;
1463 }
1464
1465 IaSize = sizeof (EFI_DHCP6_IA) + (Ia->IaAddressCount - 1) * sizeof (EFI_DHCP6_IA_ADDRESS);
1466 CopyMem (NewIa, Ia, IaSize);
1467
1468 //
1469 // Clear old address.ValidLifetime
1470 //
1471 for (Index = 0; Index < CacheIa->IaAddressCount; Index++) {
1472 CacheIa->IaAddress[Index].ValidLifetime = 0;
1473 }
1474
1475 NewIa->IaAddressCount += CacheIa->IaAddressCount;
1476 Ptr = (UINT8 *)&NewIa->IaAddress[Ia->IaAddressCount];
1477 CopyMem (Ptr, CacheIa->IaAddress, CacheIa->IaAddressCount * sizeof (EFI_DHCP6_IA_ADDRESS));
1478
1479 //
1480 // Migrate to the NewIa and free previous.
1481 //
1482 FreePool (Instance->CacheIa);
1483 FreePool (Instance->IaCb.Ia);
1484 Instance->CacheIa = NULL;
1485 Instance->IaCb.Ia = NewIa;
1486 }
1487}
1488
1501 OUT UINTN *TimeOut
1502 )
1503{
1504 EFI_STATUS Status;
1505 UINTN DataSize;
1507
1508 if ((Ip6Cfg == NULL) || (TimeOut == NULL)) {
1509 return EFI_INVALID_PARAMETER;
1510 }
1511
1512 DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
1513 Status = Ip6Cfg->GetData (
1514 Ip6Cfg,
1516 &DataSize,
1517 &DadXmits
1518 );
1519 if (EFI_ERROR (Status)) {
1520 return Status;
1521 }
1522
1523 *TimeOut = TICKS_PER_SECOND * DadXmits.DupAddrDetectTransmits + DHCP6_DAD_ADDITIONAL_DELAY;
1524
1525 return EFI_SUCCESS;
1526}
UINT64 UINTN
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
UINT16 EFIAPI ReadUnaligned16(IN CONST UINT16 *Buffer)
Definition: Unaligned.c:29
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINT32 EFIAPI WriteUnaligned32(OUT UINT32 *Buffer, IN UINT32 Value)
Definition: Unaligned.c:177
UINT16 EFIAPI WriteUnaligned16(OUT UINT16 *Buffer, IN UINT16 Value)
Definition: Unaligned.c:61
UINT32 EFIAPI ReadUnaligned32(IN CONST UINT32 *Buffer)
Definition: Unaligned.c:145
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS Dhcp6CopyConfigData(IN EFI_DHCP6_CONFIG_DATA *DstCfg, IN EFI_DHCP6_CONFIG_DATA *SorCfg)
Definition: Dhcp6Utility.c:180
EFI_STATUS Dhcp6AppendIaOption(IN OUT EFI_DHCP6_PACKET *Packet, IN OUT UINT8 **PacketCursor, IN EFI_DHCP6_IA *Ia, IN UINT32 T1, IN UINT32 T2, IN UINT32 MessageType)
Definition: Dhcp6Utility.c:824
BOOLEAN Dhcp6AddrIsInCurrentIa(IN EFI_DHCP6_IA_ADDRESS *IaAddr, IN EFI_DHCP6_IA *CurrentIa)
EFI_STATUS Dhcp6CacheIa(IN DHCP6_INSTANCE *Instance)
EFI_STATUS Dhcp6GenerateIaCb(IN DHCP6_INSTANCE *Instance, IN UINT8 *IaInnerOpt, IN UINT16 IaInnerLen, IN UINT32 T1, IN UINT32 T2)
VOID Dhcp6ParseAddrOption(IN EFI_DHCP6_IA *CurrentIa, IN UINT8 *IaInnerOpt, IN UINT16 IaInnerLen, OUT UINT32 *AddrNum, IN OUT EFI_DHCP6_IA_ADDRESS *AddrBuf)
EFI_DHCP6_IA * Dhcp6DepriveAddress(IN EFI_DHCP6_IA *Ia, IN UINT32 AddressCount, IN EFI_IPv6_ADDRESS *Addresses)
Definition: Dhcp6Utility.c:465
VOID Dhcp6AppendCacheIa(IN DHCP6_INSTANCE *Instance)
VOID EFIAPI Dhcp6OnTransmitted(IN NET_BUF *Wrap, IN UDP_END_POINT *EndPoint, IN EFI_STATUS IoStatus, IN VOID *Context)
Definition: Dhcp6Utility.c:579
EFI_DHCP6_DUID * Dhcp6GenerateClientId(IN EFI_SIMPLE_NETWORK_MODE *Mode)
Definition: Dhcp6Utility.c:33
EFI_STATUS Dhcp6AppendOption(IN OUT EFI_DHCP6_PACKET *Packet, IN OUT UINT8 **PacketCursor, IN UINT16 OptType, IN UINT16 OptLen, IN UINT8 *Data)
Definition: Dhcp6Utility.c:606
VOID Dhcp6CalculateLeaseTime(IN DHCP6_IA_CB *IaCb)
Definition: Dhcp6Utility.c:372
EFI_STATUS Dhcp6AppendIaAddrOption(IN OUT EFI_DHCP6_PACKET *Packet, IN OUT UINT8 **PacketCursor, IN EFI_DHCP6_IA_ADDRESS *IaAddr, IN UINT32 MessageType)
Definition: Dhcp6Utility.c:697
EFI_STATUS Dhcp6AppendETOption(IN OUT EFI_DHCP6_PACKET *Packet, IN OUT UINT8 **PacketCursor, IN DHCP6_INSTANCE *Instance, OUT UINT16 **Elapsed)
Definition: Dhcp6Utility.c:968
UINT8 * Dhcp6SeekOption(IN UINT8 *Buf, IN UINT32 SeekLen, IN UINT16 OptType)
VOID EFIAPI Dhcp6DummyExtFree(IN VOID *Arg)
Definition: Dhcp6Utility.c:562
VOID Dhcp6CleanupModeData(IN OUT EFI_DHCP6_MODE_DATA *ModeData)
Definition: Dhcp6Utility.c:286
EFI_STATUS Dhcp6CheckAddress(IN EFI_DHCP6_IA *Ia, IN UINT32 AddressCount, IN EFI_IPv6_ADDRESS *Addresses)
Definition: Dhcp6Utility.c:416
VOID SetElapsedTime(IN UINT16 *Elapsed, IN DHCP6_INSTANCE *Instance)
UINT32 Dhcp6CalculateExpireTime(IN UINT32 Base, IN BOOLEAN IsFirstRt, IN BOOLEAN NeedSigned)
Definition: Dhcp6Utility.c:321
UINT8 * Dhcp6SeekIaOption(IN UINT8 *Buf, IN UINT32 SeekLen, IN EFI_DHCP6_IA_DESCRIPTOR *IaDesc)
EFI_STATUS Dhcp6GetMappingTimeOut(IN EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg, OUT UINTN *TimeOut)
VOID Dhcp6CleanupConfigData(IN OUT EFI_DHCP6_CONFIG_DATA *CfgData)
Definition: Dhcp6Utility.c:251
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
@ Ip6ConfigDataTypeDupAddrDetectTransmits
Definition: Ip6Config.h:59
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define MAX(a, b)
Definition: Base.h:992
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
Definition: NetBuffer.c:195
EFI_STATUS EFIAPI NetLibGetSystemGuid(OUT EFI_GUID *SystemGuid)
Definition: DxeNetLib.c:3325
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
IPv6_ADDRESS EFI_IPv6_ADDRESS
Definition: UefiBaseType.h:90
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
Definition: UefiLib.c:1317
#define EFI_VARIABLE_NON_VOLATILE
UINT8 Duid[1]
Definition: Dhcp6.h:213
UINT16 Length
Definition: Dhcp6.h:209
UINT32 ValidLifetime
Definition: Dhcp6.h:252
EFI_DHCP6_IA_DESCRIPTOR Descriptor
Definition: Dhcp6.h:264
EFI_DHCP6_IA_ADDRESS IaAddress[1]
Definition: Dhcp6.h:281
EFI_DHCP6_STATE State
Definition: Dhcp6.h:268
UINT32 IaAddressCount
Definition: Dhcp6.h:276
UINT32 DupAddrDetectTransmits
The number of consecutive Neighbor Solicitation messages sent.
Definition: Ip6Config.h:185
Definition: Base.h:213